Перегруженные аргументы оператора всегда нулевые - PullRequest
2 голосов
/ 03 октября 2010

Итак, у меня есть класс, который переопределяет Equals (object obj) и GetHashCode () вместе с реализацией IEquatable. Чтобы сделать работу с этим типом немного более естественной при проверке на равенство, я подумал, черт возьми, я бы перегрузил оператор равенства и оператор неравенства, не беспокойтесь ...

О, беспокойство ... рассмотрим следующее - где оба экземпляра myType НЕ равны нулю:

if (myType != container.myType) //NullReferenceException
{
    //never get here
}
//never get here either

Теперь контейнер - это просто еще один класс для хранения экземпляра myType, помимо прочего, который используется для кэширования элементов.

Вот фактический (соответствующий) код из myType:

public class MyType : IEquatable<MyType>
{
    public static bool operator ==(MyType myTypeA, MyType myTypeB)
    {
        return myTypeA.Equals(myTypeB);
    }

    public static bool operator !=(MyType myTypeA, MyType myTypeB)
    {
        return !(myTypeA == myTypeB);
    }

    public override bool Equals(object obj)
    {
        if (obj != null && obj is MyType)
        {
            return Equals((MyType)obj);
        }
        return false;
    }

    public bool Equals(MyType other)
    {
        if (other != null)
        {
            return other.ToString() == ToString();
        }
        return false;
    }
}

Есть ли опыт на этом фронте?

Спасибо.

Ответы [ 3 ]

3 голосов
/ 03 октября 2010

Пара указателей -

  1. Если вы переопределили == и != для классов, обязательно используйте ReferenceEquals для проверки на нулевое значение в реализациях перегрузки, а не ==, так как это вызовет ваш перегруженный оператор и либо перейдет в цикл, либо попытается вызвать Equals по нулевой ссылке this, что, вероятно, и происходит здесь.
  2. Не переопределять == и != на занятиях.Эти операторы предназначены для равенства значений, а классы не предназначены для обеспечения равенства значений.Либо удалите перегрузки оператора, либо сделайте MyType структурой.
2 голосов
/ 03 октября 2010

Tricky one ... проблема в том, что вы используете оператор равенства внутри переопределения Equal следующим образом:

public bool Equals(MyType other)
{
    if (other != null)

Он переходит к вашему перегруженному оператору! =, Который, в свою очередь, переходит к вашему оператору ==, который пытается выполнить null.Equals ...

1 голос
/ 03 октября 2010

Как уже говорили другие, вам нужно тщательно проверить нулевые значения, так как это снова вызовет вашу функцию равенства, что обычно приводит к исключению StackOverflowException.

Когда я использую интерфейс IEquatable в классах, которые я обычно используюследующий код:

public override bool Equals(object obj)
{
    // If obj isn't MyType then 'as' will pass in null
    return this.Equals(obj as MyType);
}

public bool Equals(MyType other)
{
    if (object.ReferenceEquals(other, null))
    {
        return false;
    }

    // Actual comparison code here
    return other.ToString() == this.ToString();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...