Comment passer des paramètres à Activator.CreateInstance <T> ()

236

Je veux créer une instance d'un type que je spécifie dans une méthode générique que j'ai. Ce type a un certain nombre de constructeurs surchargés. J'aimerais pouvoir passer des arguments aux constructeurs, mais

Activator.CreateInstance<T>()

ne voit pas cela comme une option.

Y a-t-il une autre façon de procéder?

DaveDev
la source

Réponses:

458

Oui.

(T)Activator.CreateInstance(typeof(T), param1, param2);
SLaks
la source
2
J'aime cette réponse ;-)
frhack
16

Il existe une autre façon de passer des arguments à CreateInstance via des paramètres nommés.

Sur cette base, vous pouvez transmettre un tableau vers CreateInstance. Cela vous permettra d'avoir 0 ou plusieurs arguments.

public T CreateInstance<T>(params object[] paramArray)
{
  return (T)Activator.CreateInstance(typeof(T), args:paramArray);
}
sudhAnsu63
la source
2
Cela semble incomplet, vous devez sûrement retourner un objet de type T plutôt que vide? public T CreateInstance <T> (objet params [] paramArray) {return (T) Activator.CreateInstance (typeof (T), args: paramArray); }
wlf
11

Gardez à l'esprit que le fait de passer des arguments sur Activator.CreateInstance a une différence de performances significative par rapport à la création sans paramètre.

Il existe de meilleures alternatives pour créer dynamiquement des objets à l'aide de lambda précompilé. Bien sûr, les performances sont toujours subjectives et cela dépend clairement de chaque cas, que cela en vaille la peine ou non.

Détails sur le problème dans cet article.

Le graphique est tiré de l'article et représente le temps pris en ms pour 1000 appels.

Comparaison des performances

Anestis Kivranoglou
la source
Pour le contexte, ce graphique signifie que (en moyenne, sur le même matériel), chaque invocation d'un constructeur paramétré Activator.CreateInstanceprendra 0.0035ms(ou 3,5 microsecondes) - selon votre application, cela peut même ne pas du tout s'inscrire dans les tests de performances.
Dai
6

Comme alternative à Activator.CreateInstance, FastObjectFactory dans l'URL liée est meilleur qu'Activator (à partir de .NET 4.0 et nettement mieux que .NET 3.5. Aucun test / statistique effectué avec .NET 4.5). Voir le post StackOverflow pour les statistiques, les informations et le code:

Comment passer des arguments ctor dans Activator.CreateInstance ou utiliser IL?

Tamise
la source
Voulez-vous dire qu'il existe une solution alternative (liée) qui est susceptible de mieux fonctionner que Activator.CreateInstance lorsque vous passez des paramètres? Ou qui est susceptible de mieux fonctionner dans tous les cas?
El Zorko
1
Je n'ai pas fait de tests de performances depuis un moment et il semble que quelqu'un ait publié des statistiques .NET 4.0, mais oui avec .NET 4.0, il semble que FastObjectFactory ait de meilleures performances. Activator.CreateInstance était horrible dans .NET 3.5 et était beaucoup plus rapide dans .NET 4.0, mais toujours plus lent que FastObjectFactory lié dans cette URL.
thames
1
public class AssemblyLoader<T>  where T:class
{
    public void(){
        var res = Load(@"C:\test\paquete.uno.dos.test.dll", "paquete.uno.dos.clasetest.dll") 
    }

    public T Load(string assemblyFile, string objectToInstantiate) 
    {
        var loaded = Activator.CreateInstanceFrom(assemblyFile, objectToInstantiate).Unwrap();

        return loaded as T;
    }
}
Carga dinamica de dll
la source
1
Il s'agit uniquement de code inexpliqué. Je doute que cela aide ou même fonctionne du tout. Pour me convaincre du contraire, veuillez expliquer comment cela fonctionne et pourquoi cela est censé résoudre le problème.
Yunnosch