Was ist der effizienteste Weg, um den Standardkonstruktor (dh den Instanzkonstruktor ohne Parameter) eines System.Type abzurufen?
Ich habe etwas in Anlehnung an den folgenden Code gedacht, aber es scheint, dass es einen einfacheren und effizienteren Weg geben sollte, dies zu tun.
Type type = typeof(FooBar)
BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
type.GetConstructors(flags)
.Where(constructor => constructor.GetParameters().Length == 0)
.First();
c#
.net
reflection
Wes Haggard
quelle
quelle
Wenn Sie das ConstructorInfo-Objekt tatsächlich benötigen , lesen Sie die Antwort von Curt Hagenlocher .
Auf der anderen Seite, wenn Sie wirklich nur versuchen, ein Objekt zur Laufzeit aus a zu erstellen
System.Type
, sehen SieSystem.Activator.CreateInstance
- es ist nicht nur zukunftssicher (Activator verarbeitet mehr Details alsConstructorInfo.Invoke
), es ist auch viel weniger hässlich.quelle
Wenn Sie den generischen Typparameter haben, ist Jeff Bridgmans Antwort die beste. Wenn Sie nur ein Type-Objekt haben, das den Typ darstellt, den Sie erstellen möchten, können Sie es
Activator.CreateInstance(Type)
wie von Alex Lyman vorgeschlagen verwenden, aber mir wurde gesagt, dass es langsam ist (ich habe es jedoch nicht persönlich profiliert).Wenn Sie diese Objekte jedoch sehr häufig konstruieren, gibt es einen eloquenteren Ansatz, bei dem dynamisch kompilierte Linq-Ausdrücke verwendet werden:
using System; using System.Linq.Expressions; public static class TypeHelper { public static Func<object> CreateDefaultConstructor(Type type) { NewExpression newExp = Expression.New(type); // Create a new lambda expression with the NewExpression as the body. var lambda = Expression.Lambda<Func<object>>(newExp); // Compile our new lambda expression. return lambda.Compile(); } }
Rufen Sie einfach den an Sie zurückgegebenen Delegierten an. Sie sollten diesen Delegaten zwischenspeichern, da das ständige Neukompilieren von Linq-Ausdrücken teuer sein kann. Wenn Sie den Delegaten jedoch zwischenspeichern und jedes Mal wiederverwenden, kann dies sehr schnell gehen! Ich persönlich verwende ein statisches Suchwörterbuch, das nach Typ indiziert ist. Diese Funktion ist nützlich, wenn Sie mit serialisierten Objekten arbeiten, bei denen Sie möglicherweise nur die Typinformationen kennen.
quelle
Wenn Sie nur den Standardkonstruktor zum Instanziieren der Klasse erhalten möchten und den Typ als generischen Typparameter für eine Funktion abrufen möchten, haben Sie folgende Möglichkeiten:
T NewItUp<T>() where T : new() { return new T(); }
quelle
Sie möchten FormatterServices.GetUninitializedObject (Type) ausprobieren. Dieses ist besser als Activator.CreateInstance
Diese Methode ruft den Objektkonstruktor jedoch nicht auf. Wenn Sie dort Anfangswerte festlegen, funktioniert dies nicht. Überprüfen Sie die MSDN für dieses Objekt. Http://msdn.microsoft.com/en-us/library/system.runtime .serialization.formatterservices.getuninitializedobject.aspx
Hier gibt es einen anderen Weg: http://www.ozcandegirmenci.com/post/2008/02/Create-object-instances-Faster-than-Reflection.aspx
Dieser schlägt jedoch fehl, wenn das Objekt über parametrisierte Konstruktoren verfügt
Hoffe das hilft
quelle