在编译时可能并不总是知道对象的Type ,但可能需要创建Type的实例。 如何从Type获取新的对象实例?


#1楼

public AbstractType New
{get{return (AbstractType) Activator.CreateInstance(GetType());}
}

#2楼

如果要使用默认的构造函数,那么前面介绍的使用System.Activator的解决方案可能是最方便的。 但是,如果类型缺少默认构造函数,或者您必须使用非默认构造函数,则可以选择使用反射或System.ComponentModel.TypeDescriptor 。 在反射的情况下,仅知道类型名称(及其名称空间)就足够了。

使用反射的示例:

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

使用TypeDescriptor示例:

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

#3楼

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


#4楼

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

Activator类具有一个通用变体,使它变得更容易一些:

ObjectType instance = Activator.CreateInstance<ObjectType>();

#5楼

非常简单。 假设你的类名是Car和命名空间是Vehicles ,然后传递参数作为Vehicles.Car返回类型的对象Car 。 这样,您可以动态创建任何类的任何实例。

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

如果您的完全限定名称 (在这种情况下,即Vehicles.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");

#6楼

我可以解决这个问题,因为我想为任意类实现一个简单的CloneObject方法(使用默认构造函数)

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

Public Function CloneObject(Of T As New)(ByVal src As T) As TDim result As T = NothingDim cloneable = TryCast(src, ICloneable)If cloneable IsNot Nothing Thenresult = cloneable.Clone()Elseresult = New TCopySimpleProperties(src, result, Nothing, "clone")End IfReturn result
End Function

对于非泛型,假定类型具有默认构造函数,如果没有则捕获异常。

Public Function CloneObject(ByVal src As Object) As ObjectDim result As Object = NothingDim cloneable As ICloneableTrycloneable = TryCast(src, ICloneable)If cloneable IsNot Nothing Thenresult = cloneable.Clone()Elseresult = Activator.CreateInstance(src.GetType())CopySimpleProperties(src, result, Nothing, "clone")End IfCatch ex As ExceptionTrace.WriteLine("!!! CloneObject(): " & ex.Message)End TryReturn result
End Function

#7楼

编译表达式是最好的方法! (为了提高性能,可以在运行时重复创建实例)。

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

统计资料(2012年):

    Iterations: 500000000:00:00.8481762, Activator.CreateInstance(string, string)00:00:00.8416930, Activator.CreateInstance(type)00:00:06.6236752, ConstructorInfo.Invoke00:00:00.1776255, Compiled expression00:00:00.0462197, new

统计信息(2015,.net 4.5,x64):

    Iterations: 500000000:00:00.2659981, Activator.CreateInstance(string, string)00:00:00.2603770, Activator.CreateInstance(type)00:00:00.7478936, ConstructorInfo.Invoke00:00:00.0700757, Compiled expression00:00:00.0286710, new

统计信息(2015,.net 4.5,x86):

    Iterations: 500000000:00:00.3541501, Activator.CreateInstance(string, string)00:00:00.3686861, Activator.CreateInstance(type)00:00:00.9492354, ConstructorInfo.Invoke00:00:00.0719072, Compiled expression00:00:00.0229387, new

统计信息(2017,LINQPad 5.22.02 / x64 / .NET 4.6):

    Iterations: 5000000No args00:00:00.3897563, Activator.CreateInstance(string assemblyName, string typeName)00:00:00.3500748, Activator.CreateInstance(Type type)00:00:01.0100714, ConstructorInfo.Invoke00:00:00.1375767, Compiled expression00:00:00.1337920, Compiled expression (type)00:00:00.0593664, newSingle arg00:00:03.9300630, Activator.CreateInstance(Type type)00:00:01.3881770, ConstructorInfo.Invoke00:00:00.1425534, Compiled expression00: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 Core 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<X> YCreator = Expression.Lambda<Func<X>>(Expression.New(typeof(Y).GetConstructor(Type.EmptyTypes))
).Compile();
static X CreateY_CompiledExpression()
{return YCreator();
}private static readonly Func<X> YCreator_Type = Expression.Lambda<Func<X>>(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<int, X> YCreator_Arg = Expression.Lambda<Func<int, X>>(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<X>)CreateY_CreateInstance},new {Name = "Activator.CreateInstance(Type type)", Creator = (Func<X>)CreateY_CreateInstance},new {Name = "ConstructorInfo.Invoke", Creator = (Func<X>)CreateY_Invoke},new {Name = "Compiled expression", Creator = (Func<X>)CreateY_CompiledExpression},new {Name = "Compiled expression (type)", Creator = (Func<X>)CreateY_CompiledExpression_Type},new {Name = "new", Creator = (Func<X>)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<int, X>)CreateY_CreateInstance_Arg},new {Name = "ConstructorInfo.Invoke", Creator = (Func<int, X>)CreateY_Invoke_Arg},new {Name = "Compiled expression", Creator = (Func<int, X>)CreateY_CompiledExpression_Arg},new {Name = "new", Creator = (Func<int, X>)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) {}
}

#8楼

不使用反射:

private T Create<T>() where T : class, new()
{return new T();
}

#9楼

鉴于此问题,当存在无参数的ctor时,激活器将起作用。 如果这是一个约束,请考虑使用

System.Runtime.Serialization.FormatterServices.GetSafeUninitializedObject()

#10楼

通用T t = new T(); 工作?


#11楼

此问题的一种实现是尝试调用Type的无参数构造函数:

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

这是通用方法中包含的相同方法:

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

#12楼

System命名空间中的Activator类非常强大。

将参数传递给构造函数等有很多重载。 在以下位置查看文档:

http://msdn.microsoft.com/zh-CN/library/system.activator.createinstance.aspx

或(新路径)

https://docs.microsoft.com/zh-cn/dotnet/api/system.activator.createinstance

以下是一些简单的示例:

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

如何从类型创建新的对象实例相关推荐

  1. php创建实例对象数组,php – 使用arguments数组创建新的对象实例

    我正在尝试创建一个类的新实例: $obj = new $class; 我这样做的方式是,一组通用函数会为许多类执行此操作,但现在我正在实现一些参数.现在虽然处理函数可能如下所示: function n ...

  2. sql中如何统计各种零件的总数量_如何应用GOF设计模式中的构建者模式创建复合对象实例...

    软件项目实训及课程设计指导--如何应用GOF设计模式中的构建者模式创建复合对象实例 1.GOF设计模式中的构建者模式 构建者设计模式能够将一个复杂对象(它一般为组合类)的构建过程与它的表示部件相互分离 ...

  3. 反射创建对象_如何应用Java反射技术灵活地创建程序类的对象实例

    软件项目实训及课程设计指导--如何应用Java反射技术灵活地创建程序类的对象实例 1.如何应用属性配置文件实现对系统中的配置信息进行读写操作 Java中的属性配置文件主要可以作为软件应用系统及项目的配 ...

  4. 深入探索.NET内部了解CLR如何创建运行时对象

    前言 SystemDomain, SharedDomain, and DefaultDomain. 对象布局和内存细节. 方法表布局. 方法分派(Method dispatching). 因为公共语言 ...

  5. [转载]深入探索.NET框架内部了解CLR如何创建运行时对象

    深入探索.NET框架内部了解CLR如何创建运行时对象 发布日期: 9/19/2005 | 更新日期: 9/19/2005 Hanu Kommalapati Tom Christian 本文讨论: • ...

  6. session 中对象实例在不同事务中的状态

    不同事务中执行hibernate query,则查询出来的对象会在不同session中,或一个在托管态,一个在session中管理,所以是不同实例. 如果在同一事务中的话,则多次query出来的对象实 ...

  7. 深入探索.NET框架内部了解CLR如何创建运行时对象

    为什么80%的码农都做不了架构师?>>>    本文讨论: • SystemDomain, SharedDomain, and DefaultDomain • 对象布局和内存细节. ...

  8. python类和对象实例_python的类和实例化对象

    原博文 2018-12-07 16:50 − 一切皆对象,类也是对象,类来自于元类type,如果一个类没有声明自己的元类,默认它就是元类. 即类是元类的实例,通过type(类)会显示type,而实例来 ...

  9. unity创建和销毁对象_如何创建和销毁对象

    unity创建和销毁对象 本文是我们名为" 高级Java "的学院课程的一部分. 本课程旨在帮助您最有效地使用Java. 它讨论了高级主题,包括对象创建,并发,序列化,反射等. 它 ...

最新文章

  1. Linux命令之ln软链接
  2. c++中声明和定义的区别(这个兄弟写的解决了我的疑惑)
  3. 6/7 SELECT语句:过滤(正则表达式REGEXP)
  4. 计算机通信技术用到的文献,计算机技术在通信中的应用与发展
  5. obs多推流地址_(无人直播)教程利用OBS推流抖音直播电脑屏幕或PC游戏
  6. Mysql学习总结(38)——21条MySql性能优化经验
  7. 对中文版“Siri”打个招呼吧!
  8. tensorflow错误:InvalidArgumentError (see above for traceback): Cannot assign a device for operation
  9. 学习编程,最忌纠结!
  10. jmeter处理带表单的接口请求
  11. linux ios文件是否存在,Linux如何读取iOS镜像文件
  12. 【转】GIS:为什么我和别的软件不一样
  13. js导出excel格式错误的问题
  14. 秦岭三面佛已经拆除,觉得惋惜
  15. javascript 去掉html标签,js怎么去掉html标签
  16. 网易云课堂个性化推荐实践与思考
  17. 计算机盖,盖珂珂_北京理工大学计算机学院
  18. GitHub与微信开启“秘密扫描”计划,来确保数据安全
  19. Python:游戏:测试打字速度
  20. 2018年世界杯赔率预测 -DNN

热门文章

  1. android stadio 快捷键最好的材料 android stadio大全 最牛逼的android stadio快捷键
  2. todomvp 谷歌的MVP实例
  3. Java学习笔记18
  4. JavaScript语言基础3
  5. (0012) iOS 开发之MAC 终端命令学习
  6. webpack项目中使用vue
  7. PAT甲级——1102 Invert a Binary Tree (层序遍历+中序遍历)
  8. python 音乐下载演示源代码
  9. linux 和windows 下golang安装
  10. 【搜索引擎Jediael开发笔记2】使用HttpClient下载网页至本地文件