Equals和GetHashCode是如何在匿名类型上实现的
本文关键字:类型 实现 GetHashCode Equals | 更新日期: 2023-09-27 17:58:31
帮助是这样说的:
匿名类型是直接从对象派生的类类型,并且不能强制转换为除对象之外的任何类型。编译器提供每个匿名类型的名称,尽管您的应用程序无法访问从公共语言运行库的角度来看类型与任何其他引用类型都没有什么不同。
如果程序集中的两个或多个匿名对象初始值设定项指定具有相同顺序的属性序列相同的名称和类型,编译器将对象视为相同类型。它们共享相同的编译器生成类型信息
因为匿名类型上的Equals和GetHashCode方法根据的Equals和GetHashCode方法定义属性,只有当它们的所有性质都是相等的。
这些都是真的,但怎么会呢?引用源明确显示了对象是如何进行比较的(ReferenceEquals
),并且"直接从对象派生"的类型不能具有这种特殊行为。它也与CCD_ 2中CCD_。
那么它是如何做到的呢?匿名类型如何在没有任何可见覆盖的情况下覆盖Equals()
和GetHashCode()
?
编译器为您生成GetHashCode()
和Equals()
重写。例如,从这个代码:
class Program
{
static void Main(string[] args)
{
var a = new { Text = "foo", Value = 17 };
Console.WriteLine(a);
}
}
您可以在compiled.exe中找到生成的匿名类型,其中的方法如下所示(这是dotPeek&hellip的输出;还有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);
}
相关阅读:
匿名类型上的ToString是如何工作的
为什么匿名类型Equals实现比较字段
匿名类型的相等性
为什么ValueType.GetHashCode()是这样实现的?
这些都没有直接解决您的问题,但它们确实为这些覆盖的具体实现提供了一些相关的见解。