首页 文章

如何在匿名类型上实现Equals和GetHashCode?

提问于
浏览
2

帮助说:

匿名类型是直接从对象派生的类类型,不能转换为除object之外的任何类型 . 编译器为每个匿名类型提供名称,尽管您的应用程序无法访问它 . 从公共语言运行库的角度来看,匿名类型与任何其他引用类型没有区别 . 如果程序集中的两个或多个匿名对象初始值设定项指定了具有相同顺序且具有相同名称和类型的属性序列,则编译器会将对象视为相同类型的实例 . 它们共享相同的编译器生成的类型信息 . 因为匿名类型上的Equals和GetHashCode方法是根据属性的Equals和GetHashCode方法定义的,所以同一匿名类型的两个实例只有在它们的所有属性相等时才相等 .

这些都是真的,但是怎么样?参考源明确显示了如何比较对象( ReferenceEquals )和'derives directly from object'不能具有此特殊行为的类型 . 它与 ValueType 中的 Equals 的行为也不匹配 .

那怎么办?匿名类型如何覆盖 Equals()GetHashCode() 而没有任何可见的覆盖?

1 回答

  • 6

    编译器为您生成 GetHashCode()Equals() 覆盖 . 例如,从以下代码:

    class Program
    {
        static void Main(string[] args)
        {
            var a = new { Text = "foo", Value = 17 };
    
            Console.WriteLine(a);
        }
    }
    

    你可以在编译的.exe中找到生成的匿名类型,其中方法看起来像这样(这是dotPeek的输出......还有 ToString() ):

    [DebuggerHidden]
      public override string ToString()
      {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.Append("{ Text = ");
        stringBuilder.Append((object) this.\u003CText\u003Ei__Field);
        stringBuilder.Append(", Value = ");
        stringBuilder.Append((object) this.\u003CValue\u003Ei__Field);
        stringBuilder.Append(" }");
        return ((object) stringBuilder).ToString();
      }
    
      [DebuggerHidden]
      public override bool Equals(object value)
      {
        var fAnonymousType0 = value as \u003C\u003Ef__AnonymousType0<\u003CText\u003Ej__TPar, \u003CValue\u003Ej__TPar>;
        return fAnonymousType0 != null && EqualityComparer<\u003CText\u003Ej__TPar>.Default.Equals(this.\u003CText\u003Ei__Field, fAnonymousType0.\u003CText\u003Ei__Field) && EqualityComparer<\u003CValue\u003Ej__TPar>.Default.Equals(this.\u003CValue\u003Ei__Field, fAnonymousType0.\u003CValue\u003Ei__Field);
      }
    
      [DebuggerHidden]
      public override int GetHashCode()
      {
        return -1521134295 * (-1521134295 * 512982588 + EqualityComparer<\u003CText\u003Ej__TPar>.Default.GetHashCode(this.\u003CText\u003Ei__Field)) + EqualityComparer<\u003CValue\u003Ej__TPar>.Default.GetHashCode(this.\u003CValue\u003Ei__Field);
      }
    

    相关阅读:
    How does ToString on an anonymous type work?
    Why anonymous types Equals implementation compares fields?
    Equality for anonymous types
    Why is ValueType.GetHashCode() implemented like it is?

    这些都没有直接解决您的问题,但它们确实提供了一些有关这些覆盖的具体实现的相关见解 .

相关问题