인스턴스입니다 유형에서 새로운 개체를 만드는 방법

한 가지 일만은 아니다 '유형' 알 수 있지만, 컴파일 시에 객체의 인스턴스를 만드는 데 필요한 '유형'. How do you get a 에서 새 객체를 인스턴스입니다 '유형'?

해결책

루트 '시스템' 이 '활성화' 클래스 내의 이름공간이 매우 강력합니다.

수많은 과부하를 반군지역 대한 매개 변수를 구성자를 등. 체크아웃합니다 문서용으로 http://support.

&gt. &lt http://msdn.microsoft.com/en-us/library/system.activator.createinstance.aspx>;

또는 (new path)

&gt. &lt https://docs.microsoft.com/en-us/dotnet/api/system.activator.createinstance>;

다음은 간단한 예를 들면 다음과 같다:

ObjectType instance = (ObjectType)Activator.CreateInstance(objectType);

ObjectType instance = (ObjectType)Activator.CreateInstance("MyAssembly","MyNamespace.ObjectType");
해설 (6)
ObjectType instance = (ObjectType)Activator.CreateInstance(objectType);

'클래스' 를 활성화 할 수 있는 일반 변형 이 조금 더 있다.

ObjectType instance = Activator.CreateInstance();
해설 (6)

가장 좋은 방법은 컴파일됨 표현식에서는! (거듭 만드시겠습니까 성능에 대한 예를 런타임용으로 개발하십시오).

static readonly Func YCreator = Expression.Lambda(
   Expression.New(typeof(Y).GetConstructor(Type.EmptyTypes))
 ).Compile();

X x = YCreator();

통계 (2012년):

    Iterations: 5000000
    00:00:00.8481762, Activator.CreateInstance(string, string)
    00:00:00.8416930, Activator.CreateInstance(type)
    00:00:06.6236752, ConstructorInfo.Invoke
    00:00:00.1776255, Compiled expression
    00:00:00.0462197, new

통계 (2015년, .net 4.5, x64):

    Iterations: 5000000
    00:00:00.2659981, Activator.CreateInstance(string, string)
    00:00:00.2603770, Activator.CreateInstance(type)
    00:00:00.7478936, ConstructorInfo.Invoke
    00:00:00.0700757, Compiled expression
    00:00:00.0286710, new

통계 (2015년, .net 4.5, x86):

    Iterations: 5000000
    00:00:00.3541501, Activator.CreateInstance(string, string)
    00:00:00.3686861, Activator.CreateInstance(type)
    00:00:00.9492354, ConstructorInfo.Invoke
    00:00:00.0719072, Compiled expression
    00:00:00.0229387, new

통계 (2017년, 링크파드 5.22.02/x64/.NET 4.6):

    Iterations: 5000000
    No args
    00:00:00.3897563, Activator.CreateInstance(string assemblyName, string typeName)
    00:00:00.3500748, Activator.CreateInstance(Type type)
    00:00:01.0100714, ConstructorInfo.Invoke
    00:00:00.1375767, Compiled expression
    00:00:00.1337920, Compiled expression (type)
    00:00:00.0593664, new
    Single arg
    00:00:03.9300630, Activator.CreateInstance(Type type)
    00:00:01.3881770, ConstructorInfo.Invoke
    00:00:00.1425534, Compiled expression
    00:00:00.0717409, new

통계 (2019년, x64/.NET 4.8):

Iterations: 5000000
No args
00:00:00.3287835, Activator.CreateInstance(string assemblyName, string typeName)
00:00:00.3122015, Activator.CreateInstance(Type type)
00:00:00.8035712, ConstructorInfo.Invoke
00:00:00.0692854, Compiled expression
00:00:00.0662223, Compiled expression (type)
00:00:00.0337862, new
Single arg
00:00:03.8081959, Activator.CreateInstance(Type type)
00:00:01.2507642, ConstructorInfo.Invoke
00:00:00.0671756, Compiled expression
00:00:00.0301489, new

통계 (2019년, x64/.NET 핵심 3.0):

Iterations: 5000000
No args
00:00:00.3226895, Activator.CreateInstance(string assemblyName, string typeName)
00:00:00.2786803, Activator.CreateInstance(Type type)
00:00:00.6183554, ConstructorInfo.Invoke
00:00:00.0483217, Compiled expression
00:00:00.0485119, Compiled expression (type)
00:00:00.0434534, new
Single arg
00:00:03.4389401, Activator.CreateInstance(Type type)
00:00:01.0803609, ConstructorInfo.Invoke
00:00:00.0554756, Compiled expression
00:00:00.0462232, new

전체 코드:

static X CreateY_New()
{
    return new Y();
}

static X CreateY_New_Arg(int z)
{
    return new Y(z);
}

static X CreateY_CreateInstance()
{
    return (X)Activator.CreateInstance(typeof(Y));
}

static X CreateY_CreateInstance_String()
{
    return (X)Activator.CreateInstance("Program", "Y").Unwrap();
}

static X CreateY_CreateInstance_Arg(int z)
{
    return (X)Activator.CreateInstance(typeof(Y), new object[] { z, });
}

private static readonly System.Reflection.ConstructorInfo YConstructor =
    typeof(Y).GetConstructor(Type.EmptyTypes);
private static readonly object[] Empty = new object[] { };
static X CreateY_Invoke()
{
    return (X)YConstructor.Invoke(Empty);
}

private static readonly System.Reflection.ConstructorInfo YConstructor_Arg =
    typeof(Y).GetConstructor(new[] { typeof(int), });
static X CreateY_Invoke_Arg(int z)
{
    return (X)YConstructor_Arg.Invoke(new object[] { z, });
}

private static readonly Func YCreator = Expression.Lambda(
   Expression.New(typeof(Y).GetConstructor(Type.EmptyTypes))
).Compile();
static X CreateY_CompiledExpression()
{
    return YCreator();
}

private static readonly Func YCreator_Type = Expression.Lambda(
   Expression.New(typeof(Y))
).Compile();
static X CreateY_CompiledExpression_Type()
{
    return YCreator_Type();
}

private static readonly ParameterExpression YCreator_Arg_Param = Expression.Parameter(typeof(int), "z");
private static readonly Func YCreator_Arg = Expression.Lambda(
   Expression.New(typeof(Y).GetConstructor(new[] { typeof(int), }), new[] { YCreator_Arg_Param, }),
   YCreator_Arg_Param
).Compile();
static X CreateY_CompiledExpression_Arg(int z)
{
    return YCreator_Arg(z);
}

static void Main(string[] args)
{
    const int iterations = 5000000;

    Console.WriteLine("Iterations: {0}", iterations);

    Console.WriteLine("No args");
    foreach (var creatorInfo in new[]
    {
        new {Name = "Activator.CreateInstance(string assemblyName, string typeName)", Creator = (Func)CreateY_CreateInstance},
        new {Name = "Activator.CreateInstance(Type type)", Creator = (Func)CreateY_CreateInstance},
        new {Name = "ConstructorInfo.Invoke", Creator = (Func)CreateY_Invoke},
        new {Name = "Compiled expression", Creator = (Func)CreateY_CompiledExpression},
        new {Name = "Compiled expression (type)", Creator = (Func)CreateY_CompiledExpression_Type},
        new {Name = "new", Creator = (Func)CreateY_New},
    })
    {
        var creator = creatorInfo.Creator;

        var sum = 0;
        for (var i = 0; i < 1000; i++)
            sum += creator().Z;

        var stopwatch = new Stopwatch();
        stopwatch.Start();
        for (var i = 0; i < iterations; ++i)
        {
            var x = creator();
            sum += x.Z;
        }
        stopwatch.Stop();
        Console.WriteLine("{0}, {1}", stopwatch.Elapsed, creatorInfo.Name);
    }

    Console.WriteLine("Single arg");
    foreach (var creatorInfo in new[]
    {
        new {Name = "Activator.CreateInstance(Type type)", Creator = (Func)CreateY_CreateInstance_Arg},
        new {Name = "ConstructorInfo.Invoke", Creator = (Func)CreateY_Invoke_Arg},
        new {Name = "Compiled expression", Creator = (Func)CreateY_CompiledExpression_Arg},
        new {Name = "new", Creator = (Func)CreateY_New_Arg},
    })
    {
        var creator = creatorInfo.Creator;

        var sum = 0;
        for (var i = 0; i < 1000; i++)
            sum += creator(i).Z;

        var stopwatch = new Stopwatch();
        stopwatch.Start();
        for (var i = 0; i < iterations; ++i)
        {
            var x = creator(i);
            sum += x.Z;
        }
        stopwatch.Stop();
        Console.WriteLine("{0}, {1}", stopwatch.Elapsed, creatorInfo.Name);
    }
}

public class X
{
  public X() { }
  public X(int z) { this.Z = z; }
  public int Z;
}

public class Y : X
{
    public Y() {}
    public Y(int z) : base(z) {}
}
해설 (6)

이 문제는 한 구축현 security. 매개변수입니다 덜 구성자를 유형: 시도하고 있다.

public static object GetNewObject(Type t)
{
    try
    {
        return t.GetConstructor(new Type[] { }).Invoke(new object[] { });
    }
    catch
    {
        return null;
    }
}

여기에 포함된 동일한 외곽진입, 일반 방법:

public static T GetNewObject()
{
    try
    {
        return (T)typeof(T).GetConstructor(new Type[] { }).Invoke(new object[] { });
    }
    catch
    {
        return default(T);
    }
}
해설 (1)

그 아주 단순합니다. 해당 차량은 '자동차' 과 '는' classname solaris. 이름공간이 있다 '는', '자동차' 어떤 유형의 객체에는 페리클레스트카 되돌려줍니다 &prs. 전달하는 것입니다. 이렇게 모든 클래스의 인스턴스를 동적으로 문서를 만들 수 있습니다.

public object GetInstance(string strNamesapace)
{         
     Type t = Type.GetType(strNamesapace); 
     return  Activator.CreateInstance(t);         
}

[완전한 이름을] [1] 경우 (즉, '페리클레스트카' 이 경우) 는 '이' 가 또 다른 어셈블리나 메리 페리게티페 널일. 이런 경우 '유형' 모든 어셈블리나 찾을 반복하고 있다. 이를 위해 아래 코드를 사용할 수 있습니다.

public object GetInstance(string strFullyQualifiedName)
{
     Type type = Type.GetType(strFullyQualifiedName);
     if (type != null)
         return Activator.CreateInstance(type);
     foreach (var asm in AppDomain.CurrentDomain.GetAssemblies())
     {
         type = asm.GetType(strFullyQualifiedName);
         if (type != null)
             return Activator.CreateInstance(type);
     }
     return null;
 }

그리고 호출하여 인스턴스입니다 위의 방법을 활용할 수 있습니다.

object objClassInstance = GetInstance("Vehicles.Car");

[1]: https://msdn.microsoft.com/en-us/library/dfb3cx8s% 71%29.aspx 28v = vs.

해설 (2)

이 경우 캐비닛용입니다 생각하신거야 적립율은 호출됨 많이유 it& # 39 의 인스턴스입니다, 응용 프로그램에서 사용하는 대신 훨씬 빨리 컴파일하십시오 활성화 및 캐시 동적임 코드 () '또는' 콘스트러스의 포스의 보크. 두 가지 옵션이 있다 Linq 표현식에서는 또는 일부 동적 컴파일을 쉽게 컴파일됨 간단한 ['김정일' 와 '디나미스메트로트 opcode'] [2]. 어느 쪽이든, 큰 차이는 점점 를 시작할 때 긴밀한 루프 또는 여러 있다.

[2]: //www.ozcandegirmenci.com/post/2008/02/create-object-instances-faster-than-reflection.aspx http://web.archive.org/web/20140926050502/http

해설 (1)

기본 구성자를 이용하여 솔루션을 사용하려면 시스템.스티바토르 '다음' 는 아마도 가장 앞서 제시된 편리하잖아요 그러나 유형 또는 기본 중 기본 구성자를 부족하다 사용해야 합니다 사용할 수 있는 옵션이 관심용 반사 또는 '시스템.compon랑모델스티페데스크리프터'. 이름만 들어도 알 만한) 의 경우, 반사, 이는 유형 이름 (색상에는 이름공간이).

반사 사용한 예:

ObjectType instance = 
    (ObjectType)System.Reflection.Assembly.GetExecutingAssembly().CreateInstance(
        typeName: objectType.FulName, // string including namespace of the type
        ignoreCase: false,
        bindingAttr: BindingFlags.Default,
        binder: null,  // use default binder
        args: new object[] { args, to, constructor },
        culture: null, // use CultureInfo from current thread
        activationAttributes: null
    );

사용 예를 '메리 페데스크리프터':

ObjectType instance = 
    (ObjectType)System.ComponentModel.TypeDescriptor.CreateInstance(
        provider: null, // use standard type description provider, which uses reflection
        objectType: objectType,
        argTypes: new Type[] { types, of, args },
        args: new object[] { args, to, constructor }
    );
해설 (1)

39, t T T t = new wouldn& 일반 ' (),' 작동합니까?

해설 (2)

사용하지 않는 반사.

private T Create() where T : class, new()
{
    return new T();
}
해설 (7)

그러나 이 같은 문제가 있을 때 사용할 수 있는 Activator 파라메트리스 스. 구속조건으로 태그일 경우 사용하는 것이 좋습니다

System.Runtime.Serialization.FormatterServices.GetSafeUninitializedObject()
해설 (0)
public AbstractType New
{
    get
    {
        return (AbstractType) Activator.CreateInstance(GetType());
    }
}
해설 (0)

내가 할 수 있었기 때문에 이 질문에 대한 간단한 방법을 통해 구현하려는 클로네로비치 임의의 클래스 (수신기마다 기본 구성자를)

일반 함께 할 수 있는 방법이 () 는 새로운 유형.

Public Function CloneObject(Of T As New)(ByVal src As T) As T
    Dim result As T = Nothing
    Dim cloneable = TryCast(src, ICloneable)
    If cloneable IsNot Nothing Then
        result = cloneable.Clone()
    Else
        result = New T
        CopySimpleProperties(src, result, Nothing, "clone")
    End If
    Return result
End Function

비 일반 solaris. 유형 (type) 은 기본 구성자를 함께 and catch

39, doesn& 경우 예외가 없다.

Public Function CloneObject(ByVal src As Object) As Object
    Dim result As Object = Nothing
    Dim cloneable As ICloneable
    Try
        cloneable = TryCast(src, ICloneable)
        If cloneable IsNot Nothing Then
            result = cloneable.Clone()
        Else
            result = Activator.CreateInstance(src.GetType())
            CopySimpleProperties(src, result, Nothing, "clone")
        End If
    Catch ex As Exception
        Trace.WriteLine("!!! CloneObject(): " & ex.Message)
    End Try
    Return result
End Function
해설 (0)