Möglicherweise kennt man das Type
Objekt zur Kompilierungszeit nicht immer , muss jedoch möglicherweise eine Instanz des Objekts erstellen Type
.
Wie erhält man eine neue Objektinstanz von a Type
?
c#
.net
performance
reflection
types
tags2k
quelle
quelle
ObjectType instance
die Bedingung des OP überein, dass der Typ eines Objekts zur Kompilierungszeit möglicherweise nicht immer bekannt ist? : Pobject instance = Activator.CreateInstance(...);
.Die
Activator
Klasse hat eine generische Variante, die dies etwas einfacher macht:quelle
dynamic
Konstrukt , das tut solchen Konstrukte erlaubt , aber für die meisten Zwecke dieser Antwort noch bedeckt.Kompilierter Ausdruck ist der beste Weg! (Damit die Leistung zur Laufzeit wiederholt eine Instanz erstellt).
Statistik (2012):
Statistik (2015, .net 4.5, x64):
Statistik (2015, .net 4.5, x86):
Statistiken (2017, LINQPad 5.22.02 / x64 / .NET 4.6):
Statistik (2019, x64 / .NET 4.8):
Statistiken (2019, x64 / .NET Core 3.0):
Vollständiger Code:
quelle
X
zur Laufzeit ist?Type
.Eine Implementierung dieses Problems besteht darin, zu versuchen, den parameterlosen Konstruktor des Typs aufzurufen:
Hier ist der gleiche Ansatz, der in einer generischen Methode enthalten ist:
quelle
Es ist ziemlich einfach. Angenommen, Ihr Klassenname ist
Car
und der Namespace istVehicles
, und übergeben Sie den Parameter,Vehicles.Car
der ein Objekt vom Typ zurückgibtCar
. Auf diese Weise können Sie jede Instanz einer beliebigen Klasse dynamisch erstellen.Wenn sich Ihr vollständig qualifizierter Name (dh
Vehicles.Car
in diesem Fall) in einer anderen Assembly befindet, ist der NameType.GetType
null. In solchen Fällen haben Sie eine Schleife durch alle Baugruppen und finden dieType
. Dafür können Sie den folgenden Code verwendenUnd Sie können die Instanz erhalten, indem Sie die obige Methode aufrufen.
quelle
Wenn dies für etwas ist, das in einer Anwendungsinstanz häufig aufgerufen wird, ist es viel schneller, dynamischen Code zu kompilieren und zwischenzuspeichern, anstatt den Aktivator oder zu verwenden
ConstructorInfo.Invoke()
. Es werden zwei einfache Optionen für die dynamische Kompilierung kompiliert Linq Expressions oder einige einfacheIL
Opcodes undDynamicMethod
. In beiden Fällen ist der Unterschied sehr groß, wenn Sie in enge Schleifen oder mehrere Anrufe geraten.quelle
Würde das Generikum nicht
T t = new T();
funktionieren?quelle
Wenn Sie den Standardkonstruktor verwenden möchten, ist die
System.Activator
zuvor vorgestellte Lösung wahrscheinlich die bequemste. Wenn dem Typ jedoch ein Standardkonstruktor fehlt oder Sie einen nicht standardmäßigen Konstruktor verwenden müssen, können Sie Reflection oder verwendenSystem.ComponentModel.TypeDescriptor
. Im Falle einer Reflexion reicht es aus, nur den Typnamen (mit seinem Namespace) zu kennen.Beispiel mit Reflexion:
Beispiel mit
TypeDescriptor
:quelle
args[]
war genau das, was ich zu dieser Frage gefunden habe, danke!Ohne Verwendung von Reflexion:
quelle
Aufgrund dieses Problems funktioniert der Aktivator, wenn ein parameterloser Ctor vorhanden ist. Wenn dies eine Einschränkung ist, ziehen Sie die Verwendung in Betracht
quelle
quelle
Ich kann diese Frage beantworten, weil ich eine einfache CloneObject-Methode für eine beliebige Klasse (mit einem Standardkonstruktor) implementieren wollte.
Mit der generischen Methode können Sie verlangen, dass der Typ New () implementiert.
Bei nicht generischen Annahmen wird angenommen, dass der Typ einen Standardkonstruktor hat, und es wird eine Ausnahme abgefangen, wenn dies nicht der Fall ist.
quelle