Czy istnieje sposób utworzenia instancji klasy na podstawie tego, że znam nazwę klasy w czasie wykonywania. Zasadniczo miałbym nazwę klasy w ciągu.
Czy istnieje sposób utworzenia instancji klasy na podstawie tego, że znam nazwę klasy w czasie wykonywania. Zasadniczo miałbym nazwę klasy w ciągu.
Odpowiedzi:
Spójrz na metodę Activator.CreateInstance .
var driver = (OpenQA.Selenium.IWebDriver)Activator.CreateInstance("WebDriver", "OpenQA.Selenium.Firefox.FirefoxDriver").Unwrap();
To całkiem proste. Załóżmy, że twoja nazwa klasy to Car
i przestrzeń nazw to Vehicles
, a następnie przekaż parametr, Vehicles.Car
który zwraca obiekt typu Car
. W ten sposób możesz dynamicznie tworzyć dowolne wystąpienia dowolnej klasy.
public object GetInstance(string strFullyQualifiedName)
{
Type t = Type.GetType(strFullyQualifiedName);
return Activator.CreateInstance(t);
}
Jeśli twoje w pełni kwalifikowane nazwisko (tj. Vehicles.Car
W tym przypadku) znajduje się w innym zestawie, Type.GetType
będzie puste. W takich przypadkach przeglądasz wszystkie zestawy i odnajdujesz Type
. W tym celu możesz użyć poniższego kodu
public object GetInstance(string strFullyQualifiedName)
{
Type type = Type.GetType(strFullyQualifiedName);
if (type != null)
return Activator.CreateInstance(type);
foreach (var asm in AppDomain.CurrentDomain.GetAssemblies())
{
type = asm.GetType(strFullyQualifiedName);
if (type != null)
return Activator.CreateInstance(type);
}
return null;
}
Teraz, jeśli chcesz wywołać sparametryzowanego konstruktora, wykonaj następujące czynności
Activator.CreateInstance(t,17); // Incase you are calling a constructor of int type
zamiast
Activator.CreateInstance(t);
dynamic
kodu - patrz stackoverflow.com/a/2690661/904521 )
strFullyQualifiedName
z str
, fullyQualifiedName
będzie wykonać zadanie.
str
jest używane jako część konwencji nazewnictwa zmiennych. Niektóre organizacje i projekty nalegają na przestrzeganie tego, dlatego wykorzystałem. Jeśli będziesz pracował w niektórych organizacjach / projektach, będziesz o tym wiedział. Jak powiedziałeś bez, str
również wykona zadanie :) @MehdiDehghani
Z powodzeniem zastosowałem tę metodę:
System.Reflection.Assembly.GetExecutingAssembly().CreateInstance(string className)
Musisz rzutować zwrócony obiekt na wybrany typ obiektu.
Prawdopodobnie moje pytanie powinno być bardziej szczegółowe. Znam klasę bazową dla łańcucha, więc rozwiązałem ją przez:
ReportClass report = (ReportClass)Activator.CreateInstance(Type.GetType(reportClass));
Klasa Activator.CreateInstance ma różne metody osiągania tego samego na różne sposoby. Mógłbym rzucić go na obiekt, ale powyższe jest najbardziej przydatne w mojej sytuacji.
Wiem, że spóźniłem się na grę ... ale rozwiązaniem, którego szukasz, może być kombinacja powyższego i użycie interfejsu do zdefiniowania obiektów publicznie dostępnych aspektów.
Następnie, jeśli wszystkie twoje klasy, które zostałyby wygenerowane w ten sposób, implementują ten interfejs, możesz po prostu rzutować jako typ interfejsu i pracować z wynikowym obiektem.
Na przykład, jeśli przechowujesz wartości różnych typów w polu bazy danych (przechowywane jako ciąg znaków) i masz inne pole z nazwą typu (tj. String, bool, int, MyClass), to na podstawie danych tego pola możesz, utwórz klasę dowolnego typu przy użyciu powyższego kodu i wypełnij ją wartością z pierwszego pola. Zależy to oczywiście od rodzaju przechowywanego typu, który ma metodę parsowania ciągów znaków na poprawny typ. Używałem tego wiele razy do przechowywania ustawień preferencji użytkownika w bazie danych.
ReportClass report = (ReportClass)Activator.CreateInstance(Type.GetType(reportClass));
dlaczego chcesz napisać taki kod? Jeśli masz klasę „ReportClass” jest dostępna, możesz utworzyć ją bezpośrednio, jak pokazano poniżej.
ReportClass report = new ReportClass();
Kod ReportClass report = (ReportClass)Activator.CreateInstance(Type.GetType(reportClass));
jest używany, gdy nie masz dostępnej niezbędnej klasy, ale chcesz utworzyć instancję i / lub wywołać metodę dynamicznie.
Mam na myśli, że jest to przydatne, gdy znasz zestaw, ale podczas pisania kodu nie masz ReportClass
dostępnej klasy .