2015-01-09 69 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类型参数的泛型类型。

您的解决方案可能会起作用,并可能解决您的具体问题,但您必须明白它在技术上是错误的,因为如果您删除泛型类型名称的反引号部分,则实际上会合并所有泛型类型成一个名字。因此请注意,并考虑使用您的原始代码(这是正常的)以及通用类型的正确名称。