2015-01-09 73 views
0

我有一小段代碼,它檢查一個類是否存在或不存在。查找泛型反射

起初我加載所有可用的類型:

List<Type> types = new List<Type>(); 
foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies()) 
{ 
    try 
    { 
     types.AddRange(asm.GetTypes()); 
    } 
    catch (ReflectionTypeLoadException e) 
    { 
     types.AddRange(e.Types.Where(t => t != null)); 
    } 
} 

比我Concat的命名空間和類名(其中應檢查):

string fullName = ns.Trim() + "." + classToProof.Trim(); 

而且在和我請檢查是否類存在:

int found = types.Where(innerItem => innerItem.FullName == fullName).ToList().Count; 

但我有問題,如果我檢查泛型類,例如System.Collections.Generic.Dictionaryfound總是(應該是1)。

有沒有人有一個想法,爲什麼會發生這種情況?

解決方案

List<string> types = new List<string>(); 

foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies()) 
{ 
    try 
    { 
     types.AddRange(asm.GetTypes().Select(item => (!item.FullName.Contains("`") ? item.FullName : item.FullName.Substring(0, item.FullName.IndexOf("`"))))); 
    } 
    catch (ReflectionTypeLoadException e) 
    { 
     types.AddRange(e.Types.Where(t => t != null).Select(item => (!item.FullName.Contains("`") ? item.FullName : item.FullName.Substring(0, item.FullName.IndexOf("`"))))); 
    } 
} 

我刪除了所有`從全名,並填寫字符串的準備清單。

謝謝

+2

@MurrayFoxcroft這是絕對錯誤的。 –

回答

2

這可能是因爲一般用途``有一個數字,表示一般的參數計算像List`1。而你的類型名稱沒有它。爲了防止這種情況,我建議直接檢查的類型,而不是名稱:

types.Where(t => t == typeof(Dictionary<,>)) 

或者你可以使用SubstringIndexOf之前``

int found = types 
.Where(t => t.IsGenericType 
       ? t.FullName.Substring(0,t.FullName.IndexOf('`')) == fullName 
       : t.FullName == fullName).ToList().Count; 
0

對不起拿到一部分,但馬蒂亞斯是正確的,你的解決方案在技術上錯誤。

主要的問題是,在名稱空間中,具有相同名稱但具有不同類型的類型args可以同時共存。因此,這是有效的:

SomeNameSpace 
{ 
    public class MyType {}  // FullName: SomeNameSpace.MyType 
    public class MyType<T> {} // FullName: SomeNameSpace.MyType`1 
} 

所以,當你試圖找到System.Collections.Generic.Dictionary,你實際上是試圖找到一類名爲「System.Collections.Generic.Dictionary」,但與0型參數。 System.Collections.Generic中沒有這種類型。

如果您想查找System.Collections.Generic.Dictionary,那沒問題,但是該類型的全名是「System.Collections.Generic.Dictionary`2」,其中反向號碼後跟數字2意味着你談論一個2類型參數的泛型類型。

您的解決方案可能會起作用,並可能解決您的具體問題,但您必須明白它在技術上是錯誤的,因爲如果您刪除泛型類型名稱的反引號部分,則實際上會合並所有泛型類型成一個名字。因此請注意,並考慮使用您的原始代碼(這是正常的)以及通用類型的正確名稱。