Я задавался вопросом о лучшем способе реализации правильных, гибких и быстрых равных в C #, которые можно использовать практически для любого класса и ситуации . Я понял, что для производительности необходим специализированный метод Equals (принимая объект фактического класса в качестве параметра). Чтобы избежать дублирования кода, общие Equals должны вызывать специализированные Equals. Нулевые проверки должны выполняться только один раз, даже в унаследованных классах.
Я наконец-то придумал этот дизайн:
class MyClass
{
public Int32 SomeValue1 = 1;
public Int32 SomeValue2 = 25;
// Ignoring GetHashCode for simplicity.
public override bool Equals(object obj)
{
return Equals (obj as MyClass);
}
public bool Equals(MyClass obj)
{
if (obj == null) {
return false;
}
if (!SomeValue1.Equals (obj.SomeValue1)) {
return false;
}
if (!SomeValue2.Equals (obj.SomeValue2)) {
return false;
}
return true;
}
}
class MyDerivedClass : MyClass
{
public Int32 YetAnotherValue = 2;
public override bool Equals(object obj)
{
return Equals (obj as MyDerivedClass);
}
public bool Equals(MyDerivedClass obj)
{
if (!base.Equals (obj)) {
return false;
}
if (!YetAnotherValue.Equals (obj.YetAnotherValue)) {
return false;
}
return true;
}
}
Важные идеи:
- Использование оператора as. Таким образом, нам не нужно проверять наличие нулей в общих равных. Неправильные типы классов уменьшаются до нуля и будут отсортированы в специализированных Equals.
- Нулевая проверка ровно в одной точке, даже для производных классов.
- Проверка атрибутов один за другим обеспечивает четкую структуру.
Есть ли недостатки в этих концепциях, или я пропустил какие-либо условия?