以下面的课程为例:
class Sometype { int someValue; public Sometype(int someValue) { this.someValue = someValue; } }
然后我想使用反射创建这种类型的实例:
Type t = typeof(Sometype); object o = Activator.CreateInstance(t);
通常这会起作用,但是由于SomeType
没有定义无参数构造函数,调用Activator.CreateInstance
将抛出类型异常,MissingMethodException
并带有消息" 没有为此对象定义无参数构造函数. "是否还有另一种方法可以创建此类型的实例?将无参数构造函数添加到我的所有类中会有点麻烦.
我最初在这里发布了这个答案,但这里有一个转载,因为这不是完全相同的问题,但有相同的答案:
FormatterServices.GetUninitializedObject()
将在不调用构造函数的情况下创建实例.我通过使用Reflector并挖掘了一些核心的.Net序列化类来找到这个类.
我使用下面的示例代码对其进行了测试,看起来效果很好:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Reflection; using System.Runtime.Serialization; namespace NoConstructorThingy { class Program { static void Main(string[] args) { MyClass myClass = (MyClass)FormatterServices.GetUninitializedObject(typeof(MyClass)); //does not call ctor myClass.One = 1; Console.WriteLine(myClass.One); //write "1" Console.ReadKey(); } } public class MyClass { public MyClass() { Console.WriteLine("MyClass ctor called."); } public int One { get; set; } } }
使用CreateInstance方法的这个重载:
public static Object CreateInstance( Type type, params Object[] args )
使用与指定参数最匹配的构造函数创建指定类型的实例.
请参阅:http://msdn.microsoft.com/en-us/library/wcxyzt4d.aspx
当我对其性能进行基准测试时(T)FormatterServices.GetUninitializedObject(typeof(T))
,速度较慢.同时,编译后的表达式可以提高速度,尽管它们仅适用于具有默认构造函数的类型.我采用了混合方法:
public static class New{ public static readonly Func Instance = Creator(); static Func Creator() { Type t = typeof(T); if (t == typeof(string)) return Expression.Lambda >(Expression.Constant(string.Empty)).Compile(); if (t.HasDefaultConstructor()) return Expression.Lambda >(Expression.New(t)).Compile(); return () => (T)FormatterServices.GetUninitializedObject(t); } } public static bool HasDefaultConstructor(this Type t) { return t.IsValueType || t.GetConstructor(Type.EmptyTypes) != null; }
这意味着创建表达式有效地被缓存,并且仅在第一次加载类型时才会受到惩罚.将以有效的方式处理值类型.
叫它:
MyType me = New.Instance();
请注意,(T)FormatterServices.GetUninitializedObject(t)
字符串将失败.因此,字符串的特殊处理就是返回空字符串.