Übergeben von Parametern an Activator.CreateInstance <T> ()


235

Ich möchte eine Instanz eines Typs erstellen, den ich in einer generischen Methode angegeben habe. Dieser Typ verfügt über eine Reihe überladener Konstruktoren. Ich möchte in der Lage sein, Argumente an die Konstruktoren zu übergeben, aber

Activator.CreateInstance<T>()

sieht dies nicht als Option.

Gibt es einen anderen Weg, es zu tun?


Antworten:


456

Ja.

(T)Activator.CreateInstance(typeof(T), param1, param2);

2
Ich mag diese Antwort ;-)
frhack

16

Es gibt eine andere Möglichkeit, Argumente über benannte Parameter an CreateInstance zu übergeben.

Basierend darauf können Sie ein Array an übergeben CreateInstance. Auf diese Weise können Sie 0 oder mehrere Argumente haben.

public T CreateInstance<T>(params object[] paramArray)
{
  return (T)Activator.CreateInstance(typeof(T), args:paramArray);
}

2
Dies scheint unvollständig zu sein. Sicherlich müssen Sie ein Objekt vom Typ T zurückgeben, anstatt es nichtig zu machen. public T CreateInstance <T> (params object [] paramArray) {return (T) Activator.CreateInstance (typeof (T), args: paramArray); }
wlf

11

Beachten Sie jedoch, dass das Übergeben von Argumenten für Activator.CreateInstance einen erheblichen Leistungsunterschied gegenüber der parameterlosen Erstellung aufweist.

Es gibt bessere Alternativen zum dynamischen Erstellen von Objekten mit vorkompiliertem Lambda. Natürlich ist die Leistung immer subjektiv und es hängt eindeutig von jedem Fall ab, ob es sich lohnt oder nicht.

Details zum Problem in diesem Artikel.

Die Grafik stammt aus dem Artikel und zeigt die Zeit in ms pro 1000 Anrufe.

Leistungsvergleich


Für Kontext dieses Diagramm bedeutet , dass (im Durchschnitt auf derselben Hardware) jeden Aufruf einen parametrisierte Konstruktor Activator.CreateInstancenehmen 0.0035ms(oder 3,5 Mikrosekunden) - je nach Anwendung diese nicht einmal in Performance-Tests überhaupt registrieren.
Dai

6

Als Alternative zu Activator.CreateInstance ist FastObjectFactory in der verknüpften URL besser als Activator (ab .NET 4.0 und deutlich besser als .NET 3.5. Keine Tests / Statistiken mit .NET 4.5 durchgeführt). Statistiken, Informationen und Code finden Sie im StackOverflow-Beitrag:

Wie übergebe ich ctor args in Activator.CreateInstance oder verwende IL?


Meinen Sie damit, dass es eine alternative Lösung (verknüpft) gibt, die wahrscheinlich eine bessere Leistung als Activator.CreateInstance bietet, wenn Sie Parameter übergeben? Oder ist das wahrscheinlich in allen Fällen besser?
El Zorko

1
Ich habe seit einiger Zeit keine Leistungstests mehr durchgeführt und es sieht so aus, als hätte jemand .NET 4.0-Statistiken veröffentlicht, aber mit .NET 4.0 sieht es so aus, als hätte FastObjectFactory eine bessere Leistung. Activator.CreateInstance war in .NET 3.5 schrecklich und in .NET 4.0 deutlich schneller, jedoch immer noch langsamer als FastObjectFactory, das in dieser URL verlinkt ist.
Themse

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

1
Dies ist nur unerklärlicher Code. Ich bezweifle, dass es hilft oder überhaupt funktioniert. Um mich anders zu überzeugen, erklären Sie bitte, wie dies funktioniert und warum es das Problem lösen soll.
Yunnosch
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.