когда я пытаюсь перегрузить оператор == и! = в C# и переопределении, Равном, как рекомендуется, я нашел, что у меня нет способа отличить обычный объект и пустой указатель. Например, я определил класс Комплекс.
public static bool operator ==(Complex lhs, Complex rhs)
{
return lhs.Equals(rhs);
}
public static bool operator !=(Complex lhs, Complex rhs)
{
return !lhs.Equals(rhs);
}
public override bool Equals(object obj)
{
if (obj is Complex)
{
return (((Complex)obj).Real == this.Real &&
((Complex)obj).Imaginary == this.Imaginary);
}
else
{
return false;
}
}
Но когда я хочу использовать
if (temp == null)
Когда временный файл является действительно пустым, некоторое исключение происходит. И я не могу использовать ==, чтобы определить, является ли lhs пустым, который вызовет бесконечный цикл.
Что я должен сделать в этой ситуации.
Одним путем я могу думать, нам некоторая вещь как Класс. Равный (объект, объект) (если это существует) для обхода ==, когда я делаю проверку.
Что нормальный путь состоит в том, чтобы решить проблему?
Спасибо.
Вам следует рассмотреть возможность использования статического метода Equals в перегрузках оператора (который будет вызывать метод Equals экземпляра):
public static bool operator ==(Complex lhs, Complex rhs)
{
return Equals(lhs, rhs);
}
public static bool operator !=(Complex lhs, Complex rhs)
{
return !Equals(lhs, rhs);
}
Примечание: Вы также можете проверить наличие null
в методе Equals.
Вы также можете прочитать Object.Equals Topic на MSDN, который является отличным источником примеров.
Вы можете использовать следующее в верхней части вашего переопределения Equals:
if (Object.ReferenceEquals(obj, null))
return false;
Исключение, которое вы получаете, вероятно, является StackOverflowException, потому что ваш оператор == вызывает бесконечную рекурсию.
EDIT:
Если Complex является структурой, у вас не должно быть проблем с NullReferenceExceptions. Если Complex является классом, вы можете изменить реализацию перегрузок операторов == и !=, чтобы избежать исключения (Laurent Etiemble уже указал на это в своем ответе):
public static bool operator ==(Complex lhs, Complex rhs)
{
return Equals(lhs, rhs);
}
public static bool operator !=(Complex lhs, Complex rhs)
{
return !Equals(lhs, rhs);
}
public static bool operator ==(Complex lhs, Complex rhs)
{
if (Object.ReferenceEquals(lhs, null))
{
return Object.ReferenceEquals(rhs, null);
}
return lhs.Equals(rhs);
}
public static bool operator !=(Complex lhs, Complex rhs)
{
return !(lhs == rhs);
}
Модульный тест для бедняков
Action<Complex, Complex> tester = (left, right) =>
{
Console.WriteLine(left == right);
Console.WriteLine(left != right);
Console.WriteLine(left == null);
Console.WriteLine(left != null);
Console.WriteLine("---");
};
tester(new Complex(), new Complex());
tester(null, new Complex());
tester(null, null);
tester(new Complex(), null);
Есть лучший подход, чем использование операторов -
и cast
:
Complex c = obj as Complex;
return (c != null) && (c.Real == this.Real) && (c.Imaginary == this.Imaginary);
Вот быстрый тест на переопределение оператора Equals
и сравнение с null
:
class Complex
{
public override bool Equals(object obj)
{
if (obj is Complex)
{
return true;
}
else
{
return false;
}
}
}
Отладка не входит в тело оператора:
var b = (new Complex() == new Complex());
Я думаю, вам следует проверить значение null в реализации оператора ==. В противном случае, когда lhs имеет значение null, вы должны вызвать Complex (null) .Equals (я не знаю для C #, но в Java это будет исключение Nullpointer)
Чтобы проверить значение null, я предлагаю что-то вроде:
if (null == lhs && null == rhs) return true
else if (null == lhs) return false
else return lhs.Equals(rhs);
Итак, Object.Equals будет вызываться для всех == сравнений выше.