为什么属性的 Equals 方法比较字段?

Why does Equals method of attributes compare fields?

当我检查属性是否相等时,我注意到它们已经有 Equals 比较字段的方法。对于自定义 类 不会发生这种比较,因为它对性能不利,但为什么对属性进行例外处理?

这是用于确保的代码:

public class MyAttribute : Attribute
{
    public int Value { get; }
    public MyAttribute(int value) => Value = value;
}

public class MyClass
{
    public int Value { get; }
    public MyClass(int value) => Value = value;
}

public class Test
{
    [Test]
    public void TestEquals()
    {
        var myAttributeLeft = new MyAttribute(1);
        var myAttributeRight = new MyAttribute(1);
        var attributeEqualityResult = myAttributeLeft.Equals(myAttributeRight);
        Console.WriteLine(attributeEqualityResult); // true
        
        var myClassLeft = new MyClass(1);
        var myClassRight = new MyClass(1);
        var classEqualityResult = myClassLeft.Equals(myClassRight);
        Console.WriteLine(classEqualityResult); // false
    }
}

简短回答:System.Attribute 实现了自己的 Equals 实现,这与 System.Object 中的不同(MyClass class 继承)

您可以在 ms docs

上找到更详细的答案

自定义属性不适用于域对象:它们明确用于表示在编译时硬编码的元数据。假设它们按预期使用,这会赋予它们一些特殊属性:

  • 允许使用的类型有限制:通常是 intstring 等原生类型,以及这些原生类型的数组。
  • 可以放入该类型数组中的项目数受写入实际代码文件的项目数限制。

在域模型中,比较字段、属性和集合元素的值可能会造成巨大的性能损失:您不知道给定 class 的对象结构可能有多大,并且一个集合中可能包含数百万个项目。但是上面提到的限制意味着自定义属性的相等比较的成本非常有限。显然,.NET 的创建者认为这使得提供基本的 class 值语义是值得的,尽管文档包括 remarks 建议覆盖默认实现以使用对象相等性或硬编码值语义来代替.