Bir dizeden sınıf örneği oluşturma


218

Ç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.


Uygulamak istediğiniz çözümü açıklamış gibisiniz, ancak çözmeye çalıştığınız sorunu değil. Belki de genişletilebilirlikli bir şey yapmaya çalışıyorsunuz, bu durumda Yönetilen Genişletilebilirlik Çerçevesine göz atmanızı öneririm .
Jay Bazuzi

Yanıtlar:


159

Activator.CreateInstance yöntemine bir göz atın .


15
Harika örneklerle ilgili: stackoverflow.com/questions/493490/…
John S.

Türünüzün bulunması gerektiğinden, bu yazı da alakalı olacaktır: stackoverflow.com/questions/1825147/…
Brad Parks


4
Örneğin:var driver = (OpenQA.Selenium.IWebDriver)Activator.CreateInstance("WebDriver", "OpenQA.Selenium.Firefox.FirefoxDriver").Unwrap();
Endy Tjahjono

2
Burada önemli not: .Unwrap () uzaktan kumanda kolu geçmiş olsun böylece böylece dökümleri yapabilirsiniz. @Endy - Teşekkürler
Roger Willcocks

77

Oldukça basit. Sınıf adınızın Carve ad alanının olduğunu varsayalım Vehicles, ardından Vehicles.Cartü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.Carbu durumda) montaj diğerinde ise, Type.GetTypeboş 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);

Döküm olmadan nasıl kullanılır ve verilen dizeden döküm nasıl yapılır ?
TaW

1
@TaW - bir sınıf örneği kullanmak için ne yapacağına dair biraz bilgi sahibi olmanız gerekir - aksi takdirde onu kullanamazsınız. Bunun için en yaygın kullanım durumu, size önceden tanımlanmış bir sözleşme sağlayan bazı arayüzlere döküm yapmak olacaktır. ( dynamicKod kullanmadığınız sürece bu geçerlidir - bkz. Stackoverflow.com/a/2690661/904521 )
Tomer Cagan

1
'S adına değişkenin türünü kodlamak etmeyin, örneğin:. Önek gerek yoktur strFullyQualifiedNameile str, fullyQualifiedNameiş yapacak.
Mehdi Dehghani

Anahtar kelime 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 strgibi bu işi yapacak :) @MehdiDehghani
Sarath Avanavu

1
Biliyorum, herhangi bir kuruluşta adlandırma kuralları hakkında bilgi sahibi olmak için çalışmaya gerek yoktur, bu Macarca gösterim olarak bilinen bu sözleşme , kötü ve onaylanmamış adlandırma kurallarından biridir. C # için özel
Mehdi Dehghani

55

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.


9
Sınıf adı ile nesne oluşturma ve daha sonra bu tür olarak herhangi bir anlam ifade eder gibi döküm bir senaryo hayal etmeye çalışıyorum.
MusiGenesis

13
Ne demek istediğini anlıyorum. Gereksiz görünüyor. Sınıf adını biliyorsanız, neden dinamik dizeye ihtiyacınız var? Bir durum, bir temel sınıfa ve dizgeye yayınlamanızın o temel sınıfın torunlarını temsil etmesi olabilir.
Ray Li

4
Temel sınıf biliniyorsa, alt sınıfı veya bir arabirimini bağımsız değişken olarak yansımadan iletmek için bağımsız değişken olarak kullanabilirsiniz.
Garet Claborn

3
Yararlı senaryo: sadece serileştirme arabirimlerine veya diğer oldukça yaygın bir arabirime ihtiyacınız vardır. Sınıfa
atmayacaksınız

2
Verilen dizeden döküm nasıl yapılır ??
Taw

23

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ı.


4
Soru bölümünde yanıt vermek yerine, sorunuzu düzenlemenizi ve değişiklikleri not etmenizi öneririm. Bunu yapmak için daha fazla / daha iyi cevaplar alacaksınız.
Jason Jackson

İşinize yarayan özel kod satırını gönderdiğiniz için teşekkür ederiz. Tüm CreateInstance aşırı yükleri ve Türler oluşturmanın farklı yolları arasında sıralama yapmak, beni kurtardığınız çok zaman alıyordu.
Ethel Evans

4

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.


4

Çö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");

3

Ö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.


-11
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 ReportClassmevcut sınıf yok demek .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.