通用类型不相等

时间:2009-02-04 14:38:52

标签: c# .net generics

下面的代码段打印出“类型不一样。”。为什么?我知道使用interfaceOnMyType.GetGenericTypeDefinition()将解决问题,但为什么我必须这样做?

class Program
{
    static void Main(string[] args)
    {
        var myType = typeof(Baz<>);
        var interfaceOnMyType = myType.GetInterfaces().SingleOrDefault();
        var exactType = typeof(IBar<>);
        if (exactType == interfaceOnMyType)
        {
            Console.WriteLine("The types ARE the same.");
        }
        else
        {
            Console.WriteLine("The types ARE NOT the same.");
        }
        Console.ReadLine();
    }
}

interface IBar<T>
{
}

class Baz<T> : IBar<T>
{
}

3 个答案:

答案 0 :(得分:3)

interfaceOnMyType.GetGenericTypeDefinition()

返回接口的闭合构造类型,该类型与

返回的类型不同
typeof(IBar<>)

Here is the MSDN article on GetGenericTypeDefinition,这里有一个很好的引用,解释它是如何工作的:

  

给定表示此构造类型的Type对象,GetGenericTypeDefinition方法返回泛型类型定义。


编辑(上面的答案在某些情况下是正确的,但在这个案例中是错误的):

我想我现在可能已经找到了。类型比较失败的原因是因为Type返回的myType.GetInterfaces()接近但不等于接口本身的类型。

根据MSDN

  

如果使用BaseType属性获取Derived的基类型,则生成的Type对象的FullName属性将返回null(在Visual Basic中为Nothing)。要获取非空FullName,可以使用GetGenericTypeDefinition方法获取泛型类型定义。

所以我认为这是你所看到的问题。由于基本接口是通过GetInterfaces检索的,因此该调用检索的任何类型都不会有FullNamesource)。由于它没有FullName,因此类型将会失败。

如果你要比较你不是的构造类型,那么我所写的是真实的。所以不幸的是我的第一个答案是错误的 - 我已经离开了它,以便留下的评论是有意义的。

答案 1 :(得分:0)

原因是interfaceOnMyType.IsGenericTypeDefinition返回false,而myType.IsGenericTypeDefinitionexactType.IsGenericTypeDefinition都返回true。也就是说,仅仅因为您从泛型类型定义中检索非构造泛型类型并不意味着您检索的类型本身就是泛型类型定义。

答案 2 :(得分:0)

尝试以下

            Console.WriteLine("{0}", (null != exactType.FullName) ? exactType.FullName : "null");
            Console.WriteLine("{0}", (null != interfaceOnMyType.FullName) ? interfaceOnMyType.FullName : "null");

输出结果为:

test.Program + IBar`1
null

这支持Andrew Hare在此发布的调查结果。