Сравнение элементов Combo Box и предупреждения компилятора - PullRequest
1 голос
/ 19 сентября 2008

В VisualStudio (Pro 2008) я только что заметил некоторое противоречивое поведение и подумал, есть ли за этим логическое обоснование

В проекте WinForms, если я использую строку

if(myComboBox.Items[i] == myObject)

Я получаю предупреждение компилятора, что я могу получить «Возможные непреднамеренные ссылки», когда я сравниваю объект типа с типом MyObject. Достаточно справедливо.

Однако, если я вместо этого использую интерфейс для сравнения:

if(myComboBox.Items[i] == iMyInterface)

предупреждение о компиляции исчезает.

Может кто-нибудь подумать, есть ли логическая причина, по которой это должно происходить, или просто артефакт компилятора, чтобы не проверять интерфейсы для сравнения предупреждений. Есть мысли?

РЕДАКТИРОВАТЬ В моем примере комбинированный список был привязан к списку, но этот список был создан с использованием list<IMyInterface>.Cast<MyObject>().ToList<MyObject>()

Это похоже на то, как если бы компилятор только продолжал предполагать, что я привязан к списку IMyInterface.

(Методы объектов и интерфейсов были изменены для защиты невинных)

Ответы [ 2 ]

1 голос
/ 05 октября 2008

Предупреждение компиляции для первого примера вызвано тем, что любой пользовательский оператор == для вашего класса будет проигнорирован, а ссылки сравнены (возможно, не то, что вы хотели, отсюда и предупреждение).

Невозможно указать, что оператор должен быть переопределен на интерфейсе, поэтому всегда будет сравнительным сравнением. Предупреждение не нужно, потому что вы всегда должны этого ожидать.

Вот пример переопределения оператора ==:

class Program
{
    static void Main(string[] args)
    {
        object t1 = new MyTest() { Key = 1 };
        MyTest t2 = new MyTest() { Key = 1 };

        Console.WriteLine((MyTest)t1 == t2); // Uses overriden == operator, returns true
        Console.WriteLine(t1 == t2); // Reference comparison, returns false
    }
}

public class MyTest
{
    public int Key { get; set; }

    public override bool Equals(object obj)
    {
        return this.Key == (obj as MyTest).Key;
    }

    public override int GetHashCode()
    {
        return this.Key.GetHashCode();
    }

    public static bool operator ==(MyTest t1, MyTest t2)
    {
        return t1.Equals(t2);
    }

    public static bool operator !=(MyTest t1, MyTest t2)
    {
        return !t1.Equals(t2);
    }

}

Класс MyTest считается равным, если свойство Key равно. Если вы хотите создать интерфейс, вы не можете указать, что он должен включать пользовательский оператор ==, и поэтому сравнение всегда будет сравнением ссылок (и, следовательно, ложным в случае нашего примера кода).

0 голосов
/ 19 сентября 2008

Lagerdalek,

Предупреждение генерируется, потому что вам необходимо преобразовать элемент из коллекции Items обратно в оригинальный тип, который был связан с полем со списком, перед сравнением; в противном случае вы можете получить неожиданные результаты, как предупреждает компилятор.

Вот пример:

myComboBox.DataSource = Collection<Car>;

Таким образом, если поле со списком привязано к коллекции автомобилей объектов, вы отбрасываете их перед сравнением:

if((car)myComboBox.Items[i] == thisCar)

Тогда вы не должны получать никаких предупреждений.

Другой метод, который вы могли бы сделать:

using(myComboBox.Items[i] as car){
 if(myComboBox.Items[i] == thisCar)
}

Дайте мне знать. Удачи! Я ухожу из памяти, надеюсь, я ничего не опечатал. : О)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...