перегрузка == (и! =, конечно) оператор, может я обходить ==, чтобы определить, является ли объект несуществующим

когда я пытаюсь перегрузить оператор == и! = в 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 пустым, который вызовет бесконечный цикл.

Что я должен сделать в этой ситуации.

Одним путем я могу думать, нам некоторая вещь как Класс. Равный (объект, объект) (если это существует) для обхода ==, когда я делаю проверку.

Что нормальный путь состоит в том, чтобы решить проблему?

Спасибо.

17
задан LLS 9 June 2010 в 12:59
поделиться

5 ответов

Вам следует рассмотреть возможность использования статического метода 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, который является отличным источником примеров.

12
ответ дан 30 November 2019 в 12:50
поделиться

Вы можете использовать следующее в верхней части вашего переопределения 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);
} 
14
ответ дан 30 November 2019 в 12:50
поделиться
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);
2
ответ дан 30 November 2019 в 12:50
поделиться

Есть лучший подход, чем использование операторов - и 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());
0
ответ дан 30 November 2019 в 12:50
поделиться

Я думаю, вам следует проверить значение 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 будет вызываться для всех == сравнений выше.

0
ответ дан 30 November 2019 в 12:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: