在编译时可能并不总是知道对象的类型,但可能需要创建该类型的实例。
如何从类型中获得一个新的对象实例?
在编译时可能并不总是知道对象的类型,但可能需要创建该类型的实例。
如何从类型中获得一个新的对象实例?
当前回答
我可以跨越这个问题,因为我正在寻找为任意类实现一个简单的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
其他回答
不使用反射:
private T Create<T>() where T : class, new()
{
return new T();
}
答案已经给出了:
ObjectType instance = (ObjectType)Activator.CreateInstance(objectType);
然而,Activator类有一个无参数构造函数的泛型变体,通过使强制转换变得不必要,并且不需要传递对象的运行时类型,使其更具可读性:
ObjectType instance = Activator.CreateInstance<ObjectType>();
如果这是为了在应用程序实例中经常调用的东西,那么编译和缓存动态代码要比使用activator或ConstructorInfo.Invoke()快得多。动态编译的两个简单选项是编译后的Linq表达式或一些简单的IL操作码和DynamicMethod。无论哪种方式,当您开始陷入紧张的循环或多个呼叫时,差异都是巨大的。
给定这个问题,当存在无参数的ctor时,激活器将工作。如果这是一个限制,请考虑使用
System.Runtime.Serialization.FormatterServices.GetSafeUninitializedObject()
根系统名称空间中的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");