34 Stimmen

Activator.CreateInstance - Wie man Instanzen von Klassen mit parametrisierten Konstruktoren erstellt

Ich habe ein paar Bits und Bobs online über dieses Thema gelesen, aber keine gefunden, die für mich arbeiten. Was ich zu tun versuche, ist eine Klasse eines Laufzeittyps zu erstellen.

Ich benutze Activator.CreateInstance was für Klassen mit Konstruktoren, die keine Argumente enthalten, gut funktioniert. Für diejenigen mit Argumenten wirft es eine Ausnahme, gibt es eine Möglichkeit, dies zu umgehen?

Ich bin mehr als glücklich, Nullwerte oder leere Werte an den Ctor zu übergeben, solange ich die Klasse selbst erstellen kann.

52voto

Marc Gravell Punkte 970173

Es gibt eine Überladung, die Argumente als params object[] :

object obj = Activator.CreateInstance(typeof(StringBuilder), "abc");

Würde das reichen? Alternativ können Sie Reflection verwenden, um den richtigen Konstruktor zu finden:

Type[] argTypes = new Type[] {typeof(string)};
object[] argValues = new object[] {"abc"};
ConstructorInfo ctor = typeof(StringBuilder).GetConstructor(argTypes);
object obj = ctor.Invoke(argValues);

8voto

Chris Punkte 25589

Letztendlich habe ich etwas Ähnliches gemacht - einige der Kommentatoren haben diese Lösung ohnehin angedeutet.

Ich bin im Grunde alle verfügbaren Konstruktoren durchgegangen und habe den einfachsten ausgewählt. Ich schuf dann null Daten in den Ctor übergeben (für was Im mit es für diesen Ansatz ist gut)

Ein Teil des Codes sieht in etwa so aus

// If we have a ctor that requires parameters then pass null values
if (requiresParameters)
{
    List<object> parameters = new List<object>();
    ParameterInfo[] pInfos = constructorInfos[0].GetParameters();

    foreach (ParameterInfo pi in pInfos)
    {
        parameters.Add(createType(pi.ParameterType));
    }

    return constructorInfos[0].Invoke(parameters.ToArray());
}

2voto

Sam Harwell Punkte 94511

Ich verwende diese Methode, um Folgendes zu umgehen ein Problem, auf das ich gestoßen bin und es scheint genau so zu funktionieren, wie ich gehofft hatte :)

object instance = Activator.CreateInstance(
    typeof(OpCode),
    BindingFlags.NonPublic | BindingFlags.Instance,
    default(Binder),
    new object[] { stringname, pop, push, operand, type, size, s1, s2, ctrl, endsjmpblk, stack },
    default(CultureInfo));

0voto

Activator.CreateInstance hat auch eine ganze Reihe von Überladungen, eine davon ist ( Type type, params object[] args ), die Sie sich vielleicht ansehen sollten. Geben Sie einfach die erforderlichen Konstruktorargumente in den zweiten Parameter dieses Aufrufs ein.

Achten Sie jedoch darauf, dass Sie Ausnahmen behandeln, da es leicht möglich ist, falsche Parameter zu übergeben oder etwas in den Konstruktoren des Typs zu ändern, das ihn später zerstört.

0voto

thames Punkte 5553

Als Alternative zu Activator.CreateInstance schneidet FastObjectFactory in der verlinkten URL besser ab als Activator (ab .NET 4.0 und deutlich besser als .NET 3.5. Keine Tests/Statistiken mit .NET 4.5 durchgeführt). Siehe StackOverflow-Beitrag für Statistiken, Informationen und Code. Beachten Sie, dass je nach Anzahl der ctor-Parameter einige Änderungen vorgenommen werden müssen. Der mitgelieferte Code erlaubt nur 1 ctor param, kann aber geändert werden, um mehr als 1 zu haben, siehe Kommentare im Code.

Wie kann man ctor args in Activator.CreateInstance übergeben oder IL verwenden?

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X