Добавлены перегрузки операторов для сравнения двух разных объектов. Теперь не могу проверить на нуль

C # Я пытаюсь сравнить два разных объекта (сравниваю только идентичные подполя). Но у меня есть другое место, где есть проверка на нуль. Теперь у меня проблема, это проваливается в сравнении двух разных объектов, и это взрывается, потому что не ожидает null. Я попытался использовать новый метод для сравнения с объектом, но он не хочет его выбирать.

Является ли стандартной практикой при перегрузке операторов == или! = Сначала проверять какое-либо значение на null? Или есть способ сократить сравнение до нуля?


person Lee Louviere    schedule 17.11.2011    source источник


Ответы (3)


Стандартной практикой является проверка на null в операторах равенства. Возьмем, например, String:

public static bool operator ==(string a, string b)
{
    return string.Equals(a, b);
}

public static bool Equals(string a, string b)
{
    return a == b || (a != null && b != null && string.EqualsHelper(a, b));
}
person StriplingWarrior    schedule 17.11.2011

да. Вы должны проверить наличие null в своей перегрузке. И если вы перегрузите ==, вы должны перегрузить !=, а вам следует GetHashCode() и Equals().

person drdwilcox    schedule 17.11.2011
comment
Если вы перегружаете ==, вы должны перегрузить !=. - person phoog; 18.11.2011
comment
Я не стал упоминать! =, Потому что любой, у кого есть компилятор, очень быстро это поймет. - person Lee Louviere; 18.11.2011

Вы не должны перегружать == это приводит к неинтуитивному коду. Просто придерживайтесь переопределения Equals (и GetHashCode)

Взято из Оператор перегрузки == по сравнению с Equals () (ответ Самуэля Неффа)

Когда у вас есть выражение

x == y

Метод, который будет использоваться для сравнения переменных x и y, определяется во время компиляции. Это перегрузка оператора. Тип, используемый при объявлении x и y, используется для определения метода, используемого для их сравнения. Фактический тип в пределах x и y (т.е. подкласс или реализация интерфейса) не имеет значения. Обратите внимание на следующее.

object x = "hello"; object y = 'h' + "ello"; // ensure it's a different reference
x == y // evaluates to FALSE

и следующие

string x = "hello"; string y = 'h' + "ello"; // ensure it's a different reference
x == y // evaluates to TRUE

Это демонстрирует, что тип, используемый для объявления переменных x и y, используется для определения того, какой метод используется для оценки ==.

Для сравнения Equals определяется во время выполнения на основе фактического типа в переменной x. Equals - это виртуальный метод объекта, который другие типы могут переопределять и переопределяют. Следовательно, оба следующих двух примера имеют значение true.

object x = "hello"; object y = 'h' + "ello"; // ensure it's a different reference
x.Equals(y) // evaluates to TRUE

и следующие

string x = "hello"; string y = 'h' + "ello"; // ensure it's a different reference
x.Equals(y) // also evaluates to TRUE
person Rich O'Kelly    schedule 17.11.2011
comment
Я не верю, что обязательно, что "hello" и 'h' + "ello" создают разные объекты, поскольку компилятор имеет возможность оптимизировать / свернуть их. (C # 3 выполняет эту оптимизацию для string + string, но, похоже, не делает этого для char + string. Тем не менее, я сомневаюсь, что выполнение такой оптимизации противоречит спецификации, если это будет сочтено полезным.) - person ; 18.11.2011
comment
Я не уверен, что согласен с ответом Сэмюэля Неффа. overloading == позволяет программистам писать интуитивно понятный код. Мы редко прибегаем к сравнению на уровне object двух элементов, и в этом случае имеет смысл использовать .Equals(). Да, вы можете получить странные результаты, но это не повод отказываться от очень распространенной идиомы. - person drdwilcox; 18.11.2011