2011-12-14 15 views
30

C# programım var, bir ad alanı, sınıf veya yöntem varsa çalışma zamanında nasıl kontrol edebilirim? Ayrıca, sınıfa biçiminde adını kullanarak bir sınıf nasıl örneklendirilir?C# - C# ad alanı, sınıf veya yöntem olup olmadığını nasıl kontrol edilir?

yalancı kod:

string @namespace = "MyNameSpace"; 
string @class = "MyClass"; 
string method= "MyMEthod"; 

var y = IsNamespaceExists(namespace); 
var x = IsClassExists(@class)? new @class : null; //Check if exists, instantiate if so. 
var z = x.IsMethodExists(method); 
+0

bir cevap olarak en uygun yanıtı işaretlemek unutmayın. –

cevap

39

Bir sınıf yansıtmak için Type.GetType(string) kullanabilirsiniz. Type, bu tür için kullanılabilen bir yöntem de dahil olmak üzere diğer üyeleri keşfetmek için yöntemleri vardır.

Ancak, bir numara, GetType, derleme niteliğinde bir ad istiyor. Eğer sadece sınıf ismini kullanırsanız, geçerli montaja başvurduğunuzu varsayacaktır. Tabii

var type = (from assembly in AppDomain.CurrentDomain.GetAssemblies() 
      from type in assembly.GetTypes() 
      where type.Name == className 
      select type); 

, neredesiniz bundan daha fazla olabilir: Tüm yüklü meclislerinde türünü bulmak istiyorsa

Yani, böyle bir şey (LINQ kullanarak) yapabilirsiniz Henüz yüklenemeyen başvurulan derlemeler üzerinde yansıtmak istiyorum, vb.

İsim alanlarını belirlerken, yansıma bunları açıkça dışa aktarmıyor. Bunun yerine, böyle bir şey yapmak olurdu:

var type = (from assembly in AppDomain.CurrentDomain.GetAssemblies() 
       from type in assembly.GetTypes() 
       where type.Name == className && type.GetMethods().Any(m => m.Name == methodName) 
       select type).FirstOrDefault(); 

if (type == null) throw new InvalidOperationException("Valid type not found."); 

object instance = Activator.CreateInstance(type); 
+2

Örneklerinizde bir ad alanının olup olmadığını nasıl belirlersiniz? –

+0

Cevabımı güncelledi. İkinci kod örneğini kontrol edin. Yüklenen her bir derlemeyi ve her bir derlemede her bir karakteri numaralandırır ve istenen ad alanı ismine sahip herhangi bir türü ararız. – HackedByChinese

+1

Ad alanının geçerli olduğunu kontrol etmek isterseniz, sınıf adı geçerlidir ve sınıfın bir yöntemi vardır, bunu tek bir çekimde üçüncü kod örneği ile yapabilirsiniz. type.Name == className öğesinin yerini şöyle değiştirelim: type.FullName == string.Format ("{0}. {1}", namespace, className) && type.GetMethods(). Herhangi biri (m => m .Name == yöntemAdı). Ayrıca, bu örneklerde ifadenin 'select' bölümünü bırakarak bir hata yaptım. düzeltildi. – HackedByChinese

2

Bir kelime: Reflection Hepsini bir araya getirirsek

var namespaceFound = (from assembly in AppDomain.CurrentDomain.GetAssemblies() 
from type in assembly.GetTypes() 
where type.Namespace == namespace 
select type).Any() 

, gibi bir şey olurdu. Ad alanları dışında, bunları Tür isimlerini ayırmak zorunda kalacaksınız.

DÜZENLEME: Strike - ad alanları için her sınıfın hangi ad alanının ait olduğunu belirlemek için Type.Namespace özelliğini kullanmanız gerekir. (Daha fazla bilgi için bkz. HackedByChinese response).

+0

+1 Teşekkürler! Yansıma ilginç görünüyor. – dpp

25

Type bir dizgeden Type.GetType(String) yöntemini kullanarak düzeltebilirsiniz. Örneğin :

Type myType = Type.GetType("MyNamespace.MyClass"); 

Ardından bir yöntem GetMethod(String) yöntemini çağırarak tipi var olup olmadıklarını bu Tipi örneğini kullanabilirsiniz. Örneğin : hayır türü veya yöntem olarak verilen isim için ise senin tipin/yöntem yöntem çağrısı null veya değil döndü eğer kontrol ederek varsa kontrol edebilirsiniz böylece

MethodInfo myMethod = myType.GetMethod("MyMethod"); 

Hem GetType ve GetMethod, null dönün.

Son olarak, Örneğin Activator.CreateInstance(Type) kullanarak türünü örneğini:

object instance = Activator.CreateInstance(myType); 
+1

Bu, yukarıda doğru olarak işaretlenmiş olandan çok daha hızlı ve özlü bir cevaptır. Her mecliste her tür iplik eğirme, acı verici bir şekilde yavaştır. Tüm sistem derlemelerini eklerseniz, bu 10.000 yineleme döngüsü olabilir. – Deane

İlgili konular