Короче, для записи Foo, который реализуется следующим образом: var foo = new Foo { Value = "foo" и var bar = new Foo { Value = "foo" , the foo == bar Выражение приведет к True, хотя у них другая ссылка (
Код: Выделить всё
ReferenceEquals(foo, bar) // FalseТеперь с записями, хотя в статье, размещенной в блоге .Net, написано:
Если вам не нравится поведение по умолчанию при сравнении полей
сгенерированного переопределения Equals, вместо этого вы можете написать свое собственное.
Когда я попытался разместить public override bool Равно или общедоступное переопределение int GetHashCode, или общедоступный статический логический оператор == и т. д. Я получал сообщение об ошибке Member с той же подписью, которая уже объявлена, поэтому я думаю, что это ограниченное поведение, чего нельзя сказать о объектах struct.
Неудачный пример:
Код: Выделить всё
public sealed record SimpleVo
: IEquatable
{
public bool Equals(SimpleVo other) =>
throw new System.NotImplementedException();
public override bool Equals(object obj) =>
obj is SimpleVo other && Equals(other);
public override int GetHashCode() =>
throw new System.NotImplementedException();
public static bool operator ==(SimpleVo left, SimpleVo right) =>
left.Equals(right);
public static bool operator !=(SimpleVo left, SimpleVo right) =>
!left.Equals(right);
}
Код: Выделить всё
SimpleVo.cs(11,30): error CS0111: Type 'SimpleVo' already defines a member called 'Equals' with the same parameter types
SimpleVo.cs(17,37): error CS0111: Type 'SimpleVo' already defines a member called 'op_Equality' with the same parameter types
SimpleVo.cs(20,37): error CS0111: Type 'SimpleVo' already defines a member called 'op_Inequality' with the same parameter types
Один вариант использования, когда кто-то хотел бы переопределить равенство записей, потому что у вас может быть атрибут, который исключил бы свойство из проверки равенства. Возьмем, к примеру, эту реализацию ValueObject.
Затем, если вы расширите этот абстрактный класс ValueObject следующим образом:
Код: Выделить всё
public sealed class FullNameVo : ValueObject
{
public FullNameVo(string name, string surname)
{
Name = name;
Surname = surname;
}
[IgnoreMember]
public string Name { get; }
public string Surname { get; }
[IgnoreMember]
public string FullName => $"{Name} {Surname}";
}
Код: Выделить всё
var user1 = new FullNameVo("John", "Doe");
var user2 = new FullNameVo("John", "Doe");
var user3 = new FullNameVo("Jane", "Doe");
Console.WriteLine(user1 == user2); // True
Console.WriteLine(ReferenceEquals(user1, user2)); // False
Console.WriteLine(user1 == user3); // True
Console.WriteLine(user1.Equals(user3)); // True
Код: Выделить всё
public sealed record FullNameVo : ValueObject
{
[IgnoreMember]
public string Name;
public string Surname;
[IgnoreMember]
public string FullName => $"{Name} {Surname}";
}
Код: Выделить всё
var user1 = new FullNameVo
{
Name = "John",
Surname = "Doe"
};
var user2 = new FullNameVo
{
Name = "John",
Surname = "Doe"
};
var user3 = user1 with { Name = "Jane" };
Console.WriteLine(user1 == user2); // True
Console.WriteLine(ReferenceEquals(user1, user2)); // False
Console.WriteLine(user1 == user3); // False
Console.WriteLine(user1.Equals(user3)); // False
Console.WriteLine(ValueObject.EqualityComparer.Equals(user1, user3)); // True
Код: Выделить всё
dotnet --versionПодробнее здесь: https://stackoverflow.com/questions/643 ... -9-records
Мобильная версия