Почему не используется оператор == (определенный для конкретного типа)? - PullRequest
4 голосов
/ 27 апреля 2011

У меня есть список, определенный как:

var Items = new List<IItem>();

Теперь есть ряд различных классов, имеющих этот интерфейс, и один из них является Consumable.В классе Consumable также перегружен оператор ==.Теперь у меня есть следующий код и не работает:

if(item1 == item2)
{
    //code...
}

Это не работает.Я ставлю точку останова в перегрузке оператора ==, и она никогда не достигает этого.Когда я выполняю построчную отладку, оба элемента item1 и item2 имеют тип Consumable, оба GetType возвращает Consumable.Я даже попробую этот код:

var temp = item1.GetType();
var temp2 = item2.GetType();
if (temp == temp2)
{
    //code...
}

, и это равенство результатов верно.Теперь, если я попробую это:

if(((Consumable)item1) == ((Consumable)item2))
{
    //code...
}

, и это вызовет точку останова в перегрузке оператора ==.Зачем мне вручную приводить переменную, если при построчной отладке показывается, что они оба считают расходуемыми?Это потому, что я вытаскиваю их из списка IItems?

Ответы [ 4 ]

10 голосов
/ 27 апреля 2011

Поскольку ваш список List<IItem>, я предполагаю, что у вас есть что-то вроде:

var item1 = Items[0];

или что-то еще; здесь item1 переменная набирается как IItem. Разрешение оператора происходит во время сборки с помощью статического анализа (не во время выполнения с помощью полиморфизма / RTTI), поэтому единственным доступным == является значение по умолчанию для любого object, то есть равенство ссылок.

Для поддержки вашего пользовательского оператора, переменные должны быть набраны соответственно, например:

Consumable item1 = ..., item2 = ...;

Ваш актерский состав достигает аналогичной вещи.

Другой вариант - убедиться, что == и EqualsGetHashCode()) находятся в согласии, и использовать:

if(Equals(item1, item2)) {...}

, который будет делать null проверки, а затем использовать переопределенный метод Equals. Затем он поддерживает полиморфизм, поэтому не имеет значения, какие это типы.

1 голос
/ 27 апреля 2011

Обычное время выполнения языка знает только то, что ваши два объекта реализуют интерфейс IItem.Наименьшая общая часть в иерархии объектов - System.Object.И вы не перегружали оператор == System.Object.

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

0 голосов
/ 27 апреля 2011

Не должно ли быть IItem IComparable?

0 голосов
/ 27 апреля 2011

== не проверяет равенство типов, но для классов проверяет равенство ссылок.Так что, если переменные указывают на один и тот же объект, это будет верно.Например, как это:

var temp = item1;
var temp2 = item1;

if( temp == temp2 )
{
  //this code will execute
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...