Использование оператора == для операндов типа класса - PullRequest
1 голос
/ 03 марта 2011

Я хотел бы быть уверен.Если я применяю оператор == между двумя операндами типа class, он возвращает true, когда обе переменные указывают на один и тот же объект?Также как в строковом классе, для проверки равенства, например, на основе некоторого значения, мне нужно переопределить этот оператор.Это правда?

Ответы [ 5 ]

2 голосов
/ 03 марта 2011

Да, оператор == сравнивает, если ссылки указывают на один и тот же объект.

В строках он сравнивает равенство (в отличие от Java)

2 голосов
/ 03 марта 2011

Реализация по умолчанию == использует ссылочное равенство на ссылочных типах, то есть объекты равны тогда и только тогда, когда они являются одним и тем же экземпляром.

Вы можете перегрузить операторы == и !=. Если вы сделаете это, для согласованности вы также должны переопределить Equals и GetHashCode(). Если вы не переопределите их, вы получите правильное равенство только с помощью == и !=, но во многих других случаях, таких как Dictionary или HashSet, все равно будет использоваться ссылочное равенство.

Вам всегда нужно перегружать == и != вместе. Обычно я записываю само сравнение в == и выражаю другие сравнения, используя ==.

public static bool operator ==(MyClass x, MyClass y) 
{

}

public static bool operator !=(MyClass x, MyClass y) 
{
  return !(x==y);
}

public override bool Equals(object obj)
{
  if((obj==null)||(obj.GetType()!=typeof(MyClass))
    return false;
  return this==(MyClass)obj;
}

public override int GetHashCode()
{

}

И вам следует подумать о том, чтобы сделать класс неизменным. Равенство не должно изменяться, пока объект находится внутри HashSet или Dictionary, и его полная неизменность экономит много проблем. А поскольку вы можете достичь семантики значений только с помощью неизменяемых классов, и целью переопределения равенства является получение семантики значений, вам в основном нужна неизменность.

1 голос
/ 03 марта 2011

Для второго вопроса, чтобы придать == особое значение, вам действительно нужно перегрузить (а не переопределить) оператор (и! = Одновременно):

public class Test
{
    public static bool operator ==(Test t1, Test t2)
    {
        // Insert logic here, being careful of the possibility of
        // t1 and t2 being null. And don't just use if (t1 == null)
        // - it will recurse!
    }

    public static bool operator !=(Test t1, Test t2)
    {
        // Usual way of implementing
        return !(t1 == t2);
    }
}

Если вы перегружены == вы также наверняка должны:

  • Реализация IEquatable<T>
  • Вполне возможно, что ваш класс будет запечатан и неизменен (равенство, которое может изменить, вызывает беспокойство)
  • Переопределить Equals (объект) и GetHashCode
1 голос
/ 03 марта 2011

== вернет true для экземпляров x и y, если:

  • x и y относятся к одному типу
  • x и y являются либо одним и тем же экземпляром, либо тип, который они представляют, перегружен оператором ==, и в соответствии с этим они сравниваются как равные.
0 голосов
/ 03 марта 2011

Это полное объяснение из MSDN.
И да, он сравнивает ссылки экземпляров класса / объекта.

...