C# 如何比较两个泛型;“类型”;变量?
我很困惑。。。我不知道为什么会出现这个问题,我想知道是否有人能对这个问题有所帮助。我正在做一些反射操作,这需要大量的类型比较——因此,我正在存储一些以“类型”为键的信息 然而,我的两种类型,虽然表面上看起来相同,但实际上并不相同,因为当我试图查找它时,它抛出了一个“Key not Found”异常 这是我的检查员的截图: 是否有一些关于比较我可能缺少的底层类型的细节 编辑:根据Skeet先生的请求,下面是应该生成对象的整个类型树的基础类。这有点混乱,因为我已经对它进行了太多的修饰-你可以在这里看到相同的“类型”对象被添加到“myType”和“myTypeTypes”中-所以我不知道为什么它们突然变成了不同的对象C# 如何比较两个泛型;“类型”;变量?,c#,generics,reflection,types,key,C#,Generics,Reflection,Types,Key,我很困惑。。。我不知道为什么会出现这个问题,我想知道是否有人能对这个问题有所帮助。我正在做一些反射操作,这需要大量的类型比较——因此,我正在存储一些以“类型”为键的信息 然而,我的两种类型,虽然表面上看起来相同,但实际上并不相同,因为当我试图查找它时,它抛出了一个“Key not Found”异常 这是我的检查员的截图: 是否有一些关于比较我可能缺少的底层类型的细节 编辑:根据Skeet先生的请求,下面是应该生成对象的整个类型树的基础类。这有点混乱,因为我已经对它进行了太多的修饰-你可以在这里
public class TypeTree
{
private Type original;
private TypeTree subTree;
private Dictionary<Type, List<Type>> subTreeTypes = new Dictionary<Type, List<Type>>();
private List<Type> myTypes = new List<Type>();
private Dictionary<Type, List<Type>> myTypeTypes = new Dictionary<Type, List<Type>>();
public TypeTree(Type Next)
{
original = Next;
if (Next.IsGenericType)
{
myTypes.Add(Next.GetGenericTypeDefinition());
Type[] genTypes = Next.GetGenericArguments();
subTreeTypes.Add(Next.GetGenericTypeDefinition(), new List<Type>(genTypes));
}
else
{
myTypes.Add(Next);
}
Type[] lis = Next.GetInterfaces();
foreach (var v in lis)
{
if (v.IsGenericType)
{
Type genType = v.GetGenericTypeDefinition();
myTypes.Add(genType);
Type[] genTypes = v.GetGenericArguments();
myTypeTypes.Add(genType, new List<Type>());
myTypeTypes[genType].AddRange(genTypes);
}
else
{
myTypes.Add(v);
}
}
try
{
subTree = new TypeTree(Next.BaseType, myTypes, myTypeTypes, subTreeTypes, Next);
}
catch (NullReferenceException ex)
{
}
}
private TypeTree(Type Next, List<Type> MyList, Dictionary<Type, List<Type>> MyTypeTypes, Dictionary<Type, List<Type>> SubTreeTypes, Type Original)
{
if (Next.IsGenericType || Next.IsGenericTypeDefinition)
{
MyList.Add(Next.GetGenericTypeDefinition());
Type[] genTypes = Next.GetGenericArguments();
SubTreeTypes.Add(Next.GetGenericTypeDefinition(), new List<Type>(genTypes));
}
else
{
MyList.Add(Next);
SubTreeTypes.Add(Next, new List<Type>(Original.GetGenericArguments()));
}
Type[] lis = Next.GetInterfaces();
foreach (var v in lis)
{
if (v.IsGenericType)
{
Type genType = v.GetGenericTypeDefinition();
MyList.Add(genType);
Type[] genTypes = v.GetGenericArguments();
MyTypeTypes.Add(genType, new List<Type>());
MyTypeTypes[genType].AddRange(genTypes);
}
else
{
myTypes.Add(v);
}
}
try
{
subTree = new TypeTree(Next.BaseType, myTypes, MyTypeTypes, SubTreeTypes, Original);
}
catch (NullReferenceException ex)
{
}
}
public bool ReturnBestType(Dictionary<Type, MethodInfo> Search, ref MethodInfo SelectedMethod)
{
bool ret = false;
for (int i = 0; i < myTypes.Count; i++)
{
if (Search.ContainsKey(myTypes[i]))
{
if (myTypes[i].IsGenericTypeDefinition)
{
List<Type> Args = new List<Type>();
Args.Add(original);
Args.AddRange(myTypeTypes[myTypes[i]].ToArray());
MethodInfo mi = Search[myTypes[i]].MakeGenericMethod(Args.ToArray());
SelectedMethod = mi;
return true;
}
else
{
SelectedMethod = Search[myTypes[i]];
ret = true;
break;
}
}
}
return ret;
}
}
公共类类型树
{
私人类型原件;
私有类型树子树;
私有字典子目录类型=新字典();
私有列表myTypes=新列表();
私有字典myTypeTypes=新字典();
公共类型树(键入下一个)
{
原始=下一个;
if(Next.IsGenericType)
{
添加(Next.GetGenericTypeDefinition());
类型[]genTypes=Next.GetGenericArguments();
添加(Next.GetGenericTypeDefinition(),新列表(genTypes));
}
其他的
{
添加(下一步);
}
类型[]lis=Next.GetInterfaces();
foreach(lis中的var v)
{
if(v.IsGenericType)
{
类型genType=v.GetGenericTypeDefinition();
myTypes.Add(genType);
类型[]genTypes=v.GetGenericArguments();
添加(genType,newlist());
myTypeTypes[genType].AddRange(genTypes);
}
其他的
{
添加(v);
}
}
尝试
{
子树=新类型树(Next.BaseType,myTypes,myTypeTypes,subTreeTypes,Next);
}
捕获(NullReferenceException ex)
{
}
}
私有类型树(键入Next、List MyList、Dictionary MyTypeTypes、Dictionary SubTreeTypes、键入Original)
{
if(Next.IsGenericType | | Next.IsGenericTypeDefinition)
{
添加(Next.GetGenericTypeDefinition());
类型[]genTypes=Next.GetGenericArguments();
添加(Next.GetGenericTypeDefinition(),新列表(genTypes));
}
其他的
{
MyList.Add(下一步);
添加(下一步,新列表(Original.GetGenericArguments());
}
类型[]lis=Next.GetInterfaces();
foreach(lis中的var v)
{
if(v.IsGenericType)
{
类型genType=v.GetGenericTypeDefinition();
MyList.Add(genType);
类型[]genTypes=v.GetGenericArguments();
添加(genType,newlist());
MyTypeTypes[genType].AddRange(genTypes);
}
其他的
{
添加(v);
}
}
尝试
{
子树=新类型树(Next.BaseType,myTypes,MyTypeTypes,SubTreeTypes,Original);
}
捕获(NullReferenceException ex)
{
}
}
public bool ReturnBestType(字典搜索,ref MethodInfo SelectedMethod)
{
bool-ret=假;
for(int i=0;i
对于每个专门化类型,封闭泛型类型是不同的
typeof(List<int>) != typeof(List<bool>)
class MyList : List<int> {}
typeof(MyList) != typeof(List<int>)
typeof(列表)!=类型(列表)
类MyList:列表{}
类型(MyList)!=类型(列表)
您应该检查基本泛型类型和泛型参数类型
您可以对此进行调查我怀疑您遇到了问题,因为
ICollection
中的T
在每种情况下都不同。下面是一个简短但完整的示例:
using System;
interface IFoo<T> {}
public class Foo1<T> : IFoo<T> {}
public class Foo2<T> : IFoo<T> {}
class Test
{
static void Main()
{
var type1 = typeof(Foo1<>).GetInterfaces()[0];
var type2 = typeof(Foo2<>).GetInterfaces()[0];
Console.WriteLine(type1);
Console.WriteLine(type2);
Console.WriteLine(type1.Equals(type2));
}
}
现在,您可以使用Type.GetGenericTypeDefinition()
在每种情况下有效地删除T
:
Console.WriteLine(type1.GetGenericTypeDefinition()
.Equals(type2.GetGenericTypeDefinition())); // True
。。。但不清楚这是否有助于您的实际用例。如果您发布一个简短但完整的程序来演示问题,而不是一个屏幕截图,则会更有帮助。(我猜这是因为
T
s不同,顺便说一句,List
和LinkedList
实现的接口都引用了一个类型参数T
,但它是由具体类“拥有”的类型参数,因此很可能是
Console.WriteLine(type1.GetGenericTypeDefinition()
.Equals(type2.GetGenericTypeDefinition())); // True