Почему анонимные классы не реализуют System.IEquatable? ⇐ C#
Почему анонимные классы не реализуют System.IEquatable?
Анонимные классы (также известные как анонимные типы) неявно создаются и используются компилятором C# для такого кода:
var obj = new { X1 = 0, X2 = 1 }; Они имеют семантику равенства значений, т. е. метод bool Equals(object? obj) из класса object переопределяется для выполнения сравнения полей. Типичный класс C# или структура T с семантикой равенства значений реализует интерфейс System.IEquatable. Официальное руководство по реализации равенства также утверждает, что «и классы, и структуры требуют одних и тех же основных шагов для реализации равенства:
[*]
Переопределить метод виртуальный Object.Equals(Object). В большинстве случаев ваша реализация bool Equals(object obj) должна просто вызывать специфичный для типа метод Equals, который является реализацией System.IEquatable< T> интерфейс. (См. шаг 2.)
[*]
Реализуйте интерфейс System.IEquatable, предоставив зависящий от типа метод Equals».
Однако анонимные классы компилируются примерно так:
внутренний запечатанный класс AnonymousType { общественный T1 X1 {получить; } общественный T2 X2 {получить; } общественный AnonymousType (T1 x1, T2 x2) {X1 = x1; Х2 = х2; } публичное переопределение bool Equals (object? obj) { вар другой = объект как AnonymousType; вернуть это == другое || (другое != ноль && EqualityComparer.Default.Equals(X1, другое.X1) && EqualityComparer.Default.Equals(X2, другое.X2)); } public override int GetHashCode() { /* код опущен */ } общедоступная строка переопределения ToString() { /* код опущен */ } } Я ожидал, что они будут выглядеть примерно так:
внутренний запечатанный класс AnonymousType : IEquatable { общественный T1 X1 {получить; } общественный T2 X2 {получить; } общественный AnonymousType (T1 x1, T2 x2) {X1 = x1; Х2 = х2; } public bool Equals(AnonymousType? другое) => это == другое || (другое != ноль && EqualityComparer.Default.Equals(X1, другое.X1) && EqualityComparer.Default.Equals(X2, другое.X2)); публичное переопределение bool Equals(object? obj) => Equals(obj as AnonymousType); public override int GetHashCode() { /* код опущен */ } общедоступная строка переопределения ToString() { /* код опущен */ } } Возможно, я бы еще добавил операторы == и !=. (В рекомендациях говорится, что это «необязательно, но рекомендуется».)
Есть ли какая-то конкретная причина, по которой анонимные классы не реализуют IEquatable, что нарушает вышеупомянутые рекомендации?
Анонимные классы (также известные как анонимные типы) неявно создаются и используются компилятором C# для такого кода:
var obj = new { X1 = 0, X2 = 1 }; Они имеют семантику равенства значений, т. е. метод bool Equals(object? obj) из класса object переопределяется для выполнения сравнения полей. Типичный класс C# или структура T с семантикой равенства значений реализует интерфейс System.IEquatable. Официальное руководство по реализации равенства также утверждает, что «и классы, и структуры требуют одних и тех же основных шагов для реализации равенства:
[*]
Переопределить метод виртуальный Object.Equals(Object). В большинстве случаев ваша реализация bool Equals(object obj) должна просто вызывать специфичный для типа метод Equals, который является реализацией System.IEquatable< T> интерфейс. (См. шаг 2.)
[*]
Реализуйте интерфейс System.IEquatable, предоставив зависящий от типа метод Equals».
Однако анонимные классы компилируются примерно так:
внутренний запечатанный класс AnonymousType { общественный T1 X1 {получить; } общественный T2 X2 {получить; } общественный AnonymousType (T1 x1, T2 x2) {X1 = x1; Х2 = х2; } публичное переопределение bool Equals (object? obj) { вар другой = объект как AnonymousType; вернуть это == другое || (другое != ноль && EqualityComparer.Default.Equals(X1, другое.X1) && EqualityComparer.Default.Equals(X2, другое.X2)); } public override int GetHashCode() { /* код опущен */ } общедоступная строка переопределения ToString() { /* код опущен */ } } Я ожидал, что они будут выглядеть примерно так:
внутренний запечатанный класс AnonymousType : IEquatable { общественный T1 X1 {получить; } общественный T2 X2 {получить; } общественный AnonymousType (T1 x1, T2 x2) {X1 = x1; Х2 = х2; } public bool Equals(AnonymousType? другое) => это == другое || (другое != ноль && EqualityComparer.Default.Equals(X1, другое.X1) && EqualityComparer.Default.Equals(X2, другое.X2)); публичное переопределение bool Equals(object? obj) => Equals(obj as AnonymousType); public override int GetHashCode() { /* код опущен */ } общедоступная строка переопределения ToString() { /* код опущен */ } } Возможно, я бы еще добавил операторы == и !=. (В рекомендациях говорится, что это «необязательно, но рекомендуется».)
Есть ли какая-то конкретная причина, по которой анонимные классы не реализуют IEquatable, что нарушает вышеупомянутые рекомендации?
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение