在编译时可能并不总是知道对象的类型,但可能需要创建该类型的实例。

如何从类型中获得一个新的对象实例?


当前回答

根系统名称空间中的Activator类非常强大。

有很多重载用于将参数传递给构造函数等。请在以下地址查看文档:

http://msdn.microsoft.com/en-us/library/system.activator.createinstance.aspx

或者(新路径)

https://learn.microsoft.com/en-us/dotnet/api/system.activator.createinstance

这里有一些简单的例子:

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

ObjectType instance = (ObjectType)Activator.CreateInstance("MyAssembly","MyNamespace.ObjectType");

其他回答

这很简单。假设您的类名是Car,名称空间是Vehicles,然后将参数传递为Vehicles。返回Car类型的对象。像这样,您可以动态地创建任何类的任何实例。

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

如果您的完全限定名称(即车辆。在本例中,Car)位于另一个组件Type中。GetType将为null。在这种情况下,您必须遍历所有程序集并找到Type。为此,可以使用下面的代码

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");
public AbstractType New
{
    get
    {
        return (AbstractType) Activator.CreateInstance(GetType());
    }
}

我可以跨越这个问题,因为我正在寻找为任意类实现一个简单的CloneObject方法(具有默认构造函数)

使用泛型方法,您可以要求类型实现New()。

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

对于非泛型假设类型有默认构造函数和catch 如果没有,则为异常。

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

如果这是为了在应用程序实例中经常调用的东西,那么编译和缓存动态代码要比使用activator或ConstructorInfo.Invoke()快得多。动态编译的两个简单选项是编译后的Linq表达式或一些简单的IL操作码和DynamicMethod。无论哪种方式,当您开始陷入紧张的循环或多个呼叫时,差异都是巨大的。

如果要使用默认构造函数,则解决方案使用System。前面介绍的活化剂可能是最方便的。但是,如果该类型缺少默认构造函数,或者必须使用非默认构造函数,则可以使用反射或System.ComponentModel.TypeDescriptor。对于反射,只知道类型名(及其名称空间)就足够了。

使用反射的示例:

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
    );

使用TypeDescriptor的示例:

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 }
    );