Non sempre si può conoscere il Type
di un oggetto in fase di compilazione, ma si può avere bisogno di creare un'istanza del Type
. Come si ottiene un'istanza di un nuovo oggetto da un Type
?
La classe Activator
all'interno dello spazio dei nomi principale System
è piuttosto potente.
Ci sono molti sovraccarichi per passare parametri al costruttore e così via. Controlla la documentazione su:
http://msdn.microsoft.com/en-us/library/system.activator.createinstance.aspx>
o (nuovo percorso)
https://docs.microsoft.com/en-us/dotnet/api/system.activator.createinstance>
Ecco alcuni semplici esempi:
ObjectType instance = (ObjectType)Activator.CreateInstance(objectType);
ObjectType instance = (ObjectType)Activator.CreateInstance("MyAssembly","MyNamespace.ObjectType");
Un'implementazione di questo problema è tentare di chiamare il costruttore senza parametri di Type:
public static object GetNewObject(Type t)
{
try
{
return t.GetConstructor(new Type[] { }).Invoke(new object[] { });
}
catch
{
return null;
}
}
Ecco lo stesso approccio, contenuto in un metodo generico:
public static T GetNewObject<T>()
{
try
{
return (T)typeof(T).GetConstructor(new Type[] { }).Invoke(new object[] { });
}
catch
{
return default(T);
}
}
Se questo è per qualcosa che sarà chiamato spesso in un'istanza dell'applicazione, è molto più veloce compilare e mettere in cache il codice dinamico invece di usare l'attivatore o ConstructorInfo.Invoke()
. Due facili opzioni per la compilazione dinamica sono le Linq Expressions compilate o alcuni semplici opcodes IL
e DynamicMethod
. In entrambi i casi, la differenza è enorme quando si inizia a entrare in cicli stretti o chiamate multiple.