Что из IEquatable<T>
, IComparable
/ IComparable<T>
, operator ==
/ operator !=
вы также реализуете? Почему?
Я реализую IEquatable<T>
для обстоятельств, которые вы описываете. Поскольку словари будут использовать этот интерфейс, его можно использовать в ряде скрытых мест, особенно если задействован LInQ. Это будет более эффективно, чем переопределенный Equals(object)
, из-за безопасности типов и (для типов значений) отсутствия упаковки.
Обратите внимание, что GetHashCode
также необходимо переопределить, если вы изменяете семантику равенства для своего класса.
Обычно я не отменяю оператор ==, если мой тип не имеет какой-либо числовой интерпретации. То есть == /! = Вряд ли когда-либо будут единственными операторами, которые я переопределяю в классе.
Расширяете ли вы IEquatable с INode или Node? Учитывая, что IEquatable, кажется, используется только (в основном в BCL) посредством проверок типов во время выполнения, есть ли смысл расширять или не расширять INode?
Я бы добавил его к INode
, если бы ожидал когда-нибудь сравнить узлы на равенство. Если нет, то я бы не стал беспокоиться. Впрочем, может быть целесообразно, если вы работаете с коллекциями INode
.
Для тех, кого вы реализуете, вы делаете это только для самого класса или также дополнительно для идентификатора?
Если идентификатор является простым типом, например, целым числом, то, очевидно, в этом нет необходимости. Если это сложный тип, то разделение проблем потребует реализации равенства для типа идентификатора. Вот как я всегда думаю об этом: какой дизайн позволит мне вносить самые большие изменения с наименьшими усилиями? Если вы когда-нибудь решите изменить формат сложного объекта ID, то хотите ли вы обойти код, исправляющий все вещи, которые это сломает? Или вы хотите инкапсулировать всю эту логику в сам класс ID. Я бы наверняка выбрал последнее. (Это относится к ToString (), коду сериализации и ко всему прочему. Узел не имеет никакой возможности разбираться во внутренностях своего сложного типа идентификатора.)
Например, IEquatable<NodeID>
также является частью узла?
Нет, это не будет частью узла. Node
будет реализовывать IEquatable<Node>
, а NodeId
будет реализовывать IEquatable<NodeId>
.
Проверяете ли вы obj как NodeID в Equals?
Я не совсем уверен, что вы спрашиваете, но я всегда реализую переопределение object.Equals(object)
для IEquatable<T>
классов, как это:
public override bool Equals(object obj)
{
return Equals(obj as Node);
}
public bool Equals(Node node)
{
if (node == null)
return false;
// ... do the type-specific comparison.
}