使用reflection在C#中创build没有默认构造函数的types实例

以下面的课程为例:

class Sometype { int someValue; public Sometype(int someValue) { this.someValue = someValue; } } 

然后我想使用reflection来创build这种types的实例:

 Type t = typeof(Sometype); object o = Activator.CreateInstance(t); 

通常这是可行的,但是因为SomeType没有定义一个无参数的构造函数,所以对Activator.CreateInstance的调用会抛出一个types为MissingMethodException的exception,消息是“ 没有为这个对象定义无参数的构造函数是否还有另一种方法来创build这种types的实例? 将无参数的构造函数添加到我的所有类中会有点儿麻烦。

我最初在这里发布了这个答案,但这里是一个转载,因为这不是完全相同的问题,但具有相同的答案:

FormatterServices.GetUninitializedObject()将在不调用构造函数的情况下创build一个实例。 我通过使用Reflectorfind了这个类,并通过一些核心的.Net序列化类来挖掘。

我使用下面的示例代码对其进行了testing,看起来效果很好:

 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 ) 

使用最符合指定参数的构造函数创build指定types的实例。

请参阅: http : //msdn.microsoft.com/en-us/library/wcxyzt4d.aspx

当我对(T)FormatterServices.GetUninitializedObject(typeof(T))性能进行基准testing时,速度较慢。 同时编译expression式会给你很大的速度提升,尽pipe它们只能用于具有默认构造函数的types。 我采取了混合的方法:

 public static class New<T> { public static readonly Func<T> Instance = Creator(); static Func<T> Creator() { Type t = typeof(T); if (t == typeof(string)) return Expression.Lambda<Func<T>>(Expression.Constant(string.Empty)).Compile(); if (t.HasDefaultConstructor()) return Expression.Lambda<Func<T>>(Expression.New(t)).Compile(); return () => (T)FormatterServices.GetUninitializedObject(t); } } public static bool HasDefaultConstructor(this Type t) { return t.IsValueType || t.GetConstructor(Type.EmptyTypes) != null; } 

这意味着创buildexpression式被有效地caching,并且仅在该types第一次加载时才会受到惩罚。 将以有效的方式处理值types。

叫它:

 MyType me = New<MyType>.Instance(); 

请注意(T)FormatterServices.GetUninitializedObject(t)将失败的string。 因此,对string进行特殊处理以返回空string。

很好的答案,但在networking紧凑框架无法使用。 这是一个可以在CF.Net上运行的解决scheme

 class Test { int _myInt; public Test(int myInt) { _myInt = myInt; } public override string ToString() { return "My int = " + _myInt.ToString(); } } class Program { static void Main(string[] args) { var ctor = typeof(Test).GetConstructor(new Type[] { typeof(int) }); var obj = ctor.Invoke(new object[] { 10 }); Console.WriteLine(obj); } }