Μπορεί να μην γνωρίζει κανείς πάντα τον "τύπο" ενός αντικειμένου κατά τη μεταγλώττιση, αλλά μπορεί να χρειαστεί να δημιουργήσει μια περίπτωση του "τύπου". Πώς μπορείτε να πάρετε μια νέα περίπτωση αντικειμένου από έναν Type
;
Η κλάση Activator
στο χώρο ονομάτων ρίζας System
είναι αρκετά ισχυρή.
Υπάρχουν πολλές υπερφορτώσεις για τη μετάδοση παραμέτρων στον κατασκευαστή και άλλα τέτοια. Ελέγξτε την τεκμηρίωση στη διεύθυνση:
ή (νέα διαδρομή)
Ακολουθούν μερικά απλά παραδείγματα:
ObjectType instance = (ObjectType)Activator.CreateInstance(objectType);
ObjectType instance = (ObjectType)Activator.CreateInstance("MyAssembly","MyNamespace.ObjectType");
Μια υλοποίηση αυτού του προβλήματος είναι η προσπάθεια κλήσης του κατασκευαστή χωρίς παράμετρο του Type:
public static object GetNewObject(Type t)
{
try
{
return t.GetConstructor(new Type[] { }).Invoke(new object[] { });
}
catch
{
return null;
}
}
Εδώ είναι η ίδια προσέγγιση, που περιέχεται σε μια γενική μέθοδο:
public static T GetNewObject<T>()
{
try
{
return (T)typeof(T).GetConstructor(new Type[] { }).Invoke(new object[] { });
}
catch
{
return default(T);
}
}
Αν πρόκειται για κάτι που θα καλείται συχνά σε μια περίπτωση εφαρμογής, είναι πολύ πιο γρήγορο να μεταγλωττίσετε και να αποθηκεύσετε δυναμικό κώδικα αντί να χρησιμοποιήσετε τον ενεργοποιητή ή το ConstructorInfo.Invoke()
. Δύο εύκολες επιλογές για δυναμική μεταγλώττιση είναι οι μεταγλωττισμένες Linq Expressions ή κάποιες απλές IL
opcodes και DynamicMethod
. Είτε έτσι είτε αλλιώς, η διαφορά είναι τεράστια όταν αρχίζετε να μπαίνετε σε στενούς βρόχους ή πολλαπλές κλήσεις.