Другие ответы дают хорошие решения для общей проблемы.
Однако ваш собственный код можно упростить до относительно простого решения ...
Во-первых, в начале работы вашего ==
оператора у вас есть это:
// First test
if (a as object == null && b as object == null)
{
return true;
}
Это квалифицируется как "слишком усердная работа".
Если ClauseBE
является ссылочным типом, то вам нужно только сравнить с null
- «as object
» является избыточным; в равной степени, если ClauseBE
является типом значения, то оно никогда не может быть null
.
Предполагая, что ClauseBE
является ссылочным типом (наиболее вероятный случай), вы можете упростить это - обратите внимание, что мы используем Object.Equals()
, чтобы избежать бесконечной рекурсии и выброса стека.
// First test
if (Object.Equals(a, null) && Object.Equals(b, null))
{
return true;
}
Одним из полезных ярлыков является использование Object.ReferenceEquals()
- которое обрабатывает нули для вас.
Так что вы могли бы написать это вместо:
// First test
if (Object.ReferenceEquals(a, b))
{
return true;
}
с бонусом, что это также обрабатывает случай, когда a
и b
являются одинаковыми точными объектами.
Как только вы пройдете тест Object.ReferenceEquals()
, вы поймете, что a
и b
различны.
Итак, ваш следующий тест:
// Second test
if ((a as object == null && b as object != null)
|| (b as object == null && a as object != null))
{
return false;
}
можно упростить - поскольку вы знаете, что если a
равно нулю, b
не может быть равно нулю и т. Д.
// Second test
if (Object.Equals(a, null) || Object.Equals(b, null))
{
return false;
}
Если этот тест не пройден, то вы знаете, что a
и b
различны, и что ни один из них не равен нулю. Хорошее время для вызова вашего переопределенного Equals()
.
// Use the implementation of Equals() for the rest
return a.Equals(b as object);