Crear instancia de tipo sin constructor predeterminado en C # usando reflexión

Tome la siguiente clase como ejemplo:

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

Entonces quiero crear una instancia de este tipo usando reflection:

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

Normalmente, esto funcionará, sin embargo, debido a que SomeType no ha definido un constructor sin parámetros, la llamada a Activator.CreateInstance generará una excepción de tipo MissingMethodException con el mensaje ” No se definió un constructor sin parámetros para este objeto. ¿Hay alguna manera alternativa de crear un instancia de este tipo? Sería un poco sucky agregar constructores sin parámetros a todas mis clases.

Originalmente publiqué esta respuesta aquí , pero aquí hay una reimpresión ya que esta no es exactamente la misma pregunta, pero tiene la misma respuesta:

FormatterServices.GetUninitializedObject() creará una instancia sin llamar a un constructor. Encontré esta clase usando Reflector y explorando algunas de las clases principales de serialización de .Net.

Lo probé usando el siguiente código de muestra y parece que funciona muy bien:

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

Utilice esta sobrecarga del método CreateInstance:

 public static Object CreateInstance( Type type, params Object[] args ) 

Crea una instancia del tipo especificado utilizando el constructor que mejor se ajuste a los parámetros especificados.

Ver: http://msdn.microsoft.com/en-us/library/wcxyzt4d.aspx

Cuando comparé el rendimiento de (T)FormatterServices.GetUninitializedObject(typeof(T)) fue más lento. Al mismo tiempo, las expresiones comstackdas le brindarán grandes mejoras de velocidad aunque solo funcionan para los tipos con el constructor predeterminado. Tomé un enfoque híbrido:

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

Esto significa que la expresión de creación se almacena efectivamente en caché y solo incurre en penalidad la primera vez que se carga el tipo. Manejará los tipos de valor también de manera eficiente.

Llámalo:

 MyType me = New.Instance(); 

Tenga en cuenta que (T)FormatterServices.GetUninitializedObject(t) fallará para la cadena. Por lo tanto, el manejo especial de la cuerda está en su lugar para devolver una cuerda vacía.

Buenas respuestas pero inutilizables en el marco compacto de dot net. Aquí hay una solución que funcionará en CF.Net …

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