-1

When I checked the attributes for equality, I noticed that they already have Equals method that compares the fields. For custom classes this comparison does not occur, since it is bad for performance, but why was an exception made for attributes?

Here's the code to make sure:

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
    }
}
kaboom
  • 41
  • 5
  • Because `Attribute.Equals` is defined this way, see https://referencesource.microsoft.com/#mscorlib/system/attribute.cs,c8870413a6cc65f8 – Klaus Gütter May 27 '21 at 18:54

2 Answers2

0

Short answer: System.Attribute implements its own implementation of Equals which is different from the one in System.Object (from which MyClass class inherits)

You can find a more detailed answer on ms docs

user1624411
  • 398
  • 4
  • 6
0

Custom attributes are not intended for use as domain objects: they are explicitly intended to represent metadata that are hard-coded at compile time. Assuming they are used as intended, this gives them a few special properties:

  • There are limits on the types that they are allowed to use: typically native types like int and string, and arrays of those native types.
  • The number of items that could be put into an array on the type is bounded by the number of items that are written into an actual code file.

In domain models it could create enormous performance penalties to compare the values of fields, properties, and elements of collections: you don't know how big the object structure for a given class might be, and a collection could have millions of items in it. But the restrictions mentioned above mean that the cost of an equality comparison for custom attributes is pretty well bounded. Evidently the creators of .NET felt that this made it worthwhile to give the base class value semantics, although the documentation includes remarks that recommend overriding the default implementation to use object equality or hard-coded value semantics instead.

StriplingWarrior
  • 151,543
  • 27
  • 246
  • 315