Çalışma zamanında sınıfın adını biliyorum gerçeğine dayalı bir sınıf örneği oluşturmak için bir yolu var mı. Temelde bir dize sınıfın adı olurdu.
Çalışma zamanında sınıfın adını biliyorum gerçeğine dayalı bir sınıf örneği oluşturmak için bir yolu var mı. Temelde bir dize sınıfın adı olurdu.
Yanıtlar:
Activator.CreateInstance yöntemine bir göz atın .
var driver = (OpenQA.Selenium.IWebDriver)Activator.CreateInstance("WebDriver", "OpenQA.Selenium.Firefox.FirefoxDriver").Unwrap();
Oldukça basit. Sınıf adınızın Car
ve ad alanının olduğunu varsayalım Vehicles
, ardından Vehicles.Car
türün nesnesini döndüren parametreyi iletin Car
. Bunun gibi herhangi bir sınıfın dinamik bir şekilde herhangi bir örneğini oluşturabilirsiniz.
public object GetInstance(string strFullyQualifiedName)
{
Type t = Type.GetType(strFullyQualifiedName);
return Activator.CreateInstance(t);
}
Senin Eğer Tamamen Nitelikli İsim (yani Vehicles.Car
bu durumda) montaj diğerinde ise, Type.GetType
boş olacaktır. Bu gibi durumlarda, tüm montajlar arasında döngü var ve bulmak Type
. Bunun için aşağıdaki kodu kullanabilirsiniz
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;
}
Şimdi parametreli bir kurucu çağırmak istiyorsanız aşağıdakileri yapın
Activator.CreateInstance(t,17); // Incase you are calling a constructor of int type
onun yerine
Activator.CreateInstance(t);
dynamic
Kod kullanmadığınız sürece bu geçerlidir - bkz. Stackoverflow.com/a/2690661/904521 )
strFullyQualifiedName
ile str
, fullyQualifiedName
iş yapacak.
str
, değişkenler için adlandırma kuralının bir parçası olarak kullanılır. Bazı organizasyonlar ve projeler bunu takip etmekte ısrar ediyorlar, bu yüzden kullandım. Eğer bazı oraganizasyonlarda / projelerde çalışsaydınız, bunu bileceksiniz. Sizin de söylemediğiniz str
gibi bu işi yapacak :) @MehdiDehghani
Bu yöntemi başarıyla kullandım:
System.Reflection.Assembly.GetExecutingAssembly().CreateInstance(string className)
Döndürülen nesneyi istediğiniz nesne türüne atamanız gerekir.
Muhtemelen sorum daha spesifik olmalıydı. Aslında böylece tarafından çözüldü dize için bir temel sınıf biliyorum:
ReportClass report = (ReportClass)Activator.CreateInstance(Type.GetType(reportClass));
Activator.CreateInstance sınıfı, aynı şeyi farklı şekillerde elde etmek için çeşitli yöntemlere sahiptir. Bunu bir nesneye atabilirdim ama yukarıdakiler benim durumum için en yararlı olanı.
Oyuna geç kaldığımı biliyorum ... ama aradığınız çözüm yukarıdakilerin birleşimi olabilir ve nesnelerinizin herkes tarafından erişilebilir yönlerini tanımlamak için bir arayüz kullanmak olabilir.
Ardından, bu şekilde oluşturulacak tüm sınıflarınız bu arabirimi uygularsa, yalnızca arabirim türü olarak yayınlayabilir ve ortaya çıkan nesne ile çalışabilirsiniz.
Çözümdeki başka bir projeden bir sınıf örneği oluşturmak için, derlemeyi herhangi bir sınıfın adıyla (örneğin BaseEntity) gösterebilir ve yeni bir örnek oluşturabilirsiniz:
var newClass = System.Reflection.Assembly.GetAssembly(typeof(BaseEntity)).CreateInstance("MyProject.Entities.User");
Örneğin, çeşitli türlerdeki değerleri bir veritabanı alanında (dize olarak depolanır) depolar ve tür adında başka bir alana (yani, String, bool, int, MyClass) sahipseniz, bu alan verilerinden, akla uygun bir şekilde, Yukarıdaki kodu kullanarak herhangi bir türde bir sınıf oluşturun ve bu kodu ilk alandaki değerle doldurun. Bu, elbette, dizeleri doğru türe ayrıştırma yöntemine sahip olan depoladığınız türe bağlıdır. Bunu bir çok kez kullanıcı tercih ayarlarını bir veritabanında saklamak için kullandım.
ReportClass report = (ReportClass)Activator.CreateInstance(Type.GetType(reportClass));
neden böyle bir kod yazmak istiyorsun? 'ReportClass' sınıfınız varsa, aşağıda gösterildiği gibi doğrudan başlatabilirsiniz.
ReportClass report = new ReportClass();
Kod ReportClass report = (ReportClass)Activator.CreateInstance(Type.GetType(reportClass));
, gerekli sınıfa sahip olmadığınızda kullanılır, ancak bir yöntemi dinamik olarak başlatmak ve / veya çağırmak istediğinizde kullanılır.
U derlemek montajı bilmek yararlı ama kod yazarken ReportClass
mevcut sınıf yok demek .