c# - TypeDelegator 平等不一致?

标签 c# .net types equals equality

考虑以下代码:

    class MyType : TypeDelegator
    {
       public MyType(Type parent)
          : base(parent)
       {
       }
    }

    class Program
    {
       static void Main(string[] args)
       {
          Type t1 = typeof(string);
          Type t2 = new MyType(typeof(string));

          Console.WriteLine(EqualityComparer<Type>.Default.Equals(t1, t2)); // <-- false
          Console.WriteLine(EqualityComparer<Type>.Default.Equals(t2, t1)); // <-- true

          Console.WriteLine(t1.Equals(t2)); // <-- true
          Console.WriteLine(t2.Equals(t1)); // <-- true

          Console.WriteLine(Object.Equals(t1, t2)); // <-- false
          Console.WriteLine(Object.Equals(t2, t1)); // <-- true
       }
   }

为什么不同版本的 Equals 返回不同的结果? EqualityComparer.Default 可能调用 Object.Equals,因此这些结果匹配,尽管它们本身不一致。 Equals 的普通实例版本都返回 true

当方法返回实际上继承自 TypeDelegatorType 时,这显然会产生问题。想象一下,例如将这些类型作为键放在字典中,默认情况下使用 EqualityComparer.Default 进行比较。

有什么办法可以解决这个问题吗?我希望上面代码中的所有方法都返回 true

最佳答案

以下代码返回一个 System.RuntimeType

Type t1 = typeof(string);

如果您查看 Type 的代码,则有:

public override bool Equals(Object o)
{
    if (o == null) 
        return false;

    return Equals(o as Type); 
}

但是,System.RuntimeType 有:

public override bool Equals(object obj) 
{
    // ComObjects are identified by the instance of the Type object and not the TypeHandle.
    return obj == (object)this;
} 

如果您查看程序集,它会执行:cmp rdx、rcx,所以只是直接内存比较。

您可以使用以下方法重现它:

bool a = t1.Equals((object)t2); // False
bool b = t1.Equals(t2); // True

所以看起来 RuntimeType 正在覆盖 Type Equals 方法来进行直接比较......看起来没有简单的方法解决这个问题(不提供比较器)。

编辑添加: 出于好奇,我查看了 RuntimeType 的 .NET 1.0 和 1.1 实现。它们没有覆盖 RuntimeType 中的 Equals,因此该问题是在 .NET 2.0 中引入的。

关于c# - TypeDelegator 平等不一致?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7633260/

相关文章:

c# - Func<T,TResult> 是如何工作的?

c# - 为什么 datatable.Clear 也清除其他数据表?

scala - scala 中具有不同类型参数的 Varargs

.net - 在 .NET 中使用 XmlReader 转义 XML 实体?

haskell - 如何 "newtype"IntSet?

Haskell - 限制数据参数

c# - nhibernate fluent bool 到 smallint 映射

c# - Python 全局变量在赋值之前被引用

javascript - 如何计算添加元素?

c# - char 160 在我的源代码中意味着什么?