组合框项目比较和编译器警告

时间:2020-03-06 14:24:16  来源:igfitidea点击:

在VisualStudio(Pro 2008)中,我刚刚注意到一些不一致的行为,并且想知道其背后是否存在任何逻辑推理。

在WinForms项目中,如果我使用

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

我在将类型对象与MyObject类型进行比较时,收到编译器警告,可能会收到"可能的意外引用"。很公平。

但是,如果我改为使用接口与以下对象进行比较:

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

编译警告消失。

任何人都可以考虑是否有任何逻辑上的原因会导致这种情况发生,或者只是编译器的人工产物而不检查接口的比较警告。有什么想法吗?

编辑在我的示例中,组合框绑定到一个列表,但是该列表是使用list <IMyInterface> .Cast <MyObject>()。ToList <MyObject>()生成的。

好像编译器仅假设我绑定到IMyInterface列表一样。

(已更改对象和接口方法以保护无辜者)

解决方案

Lagerdalek,

之所以会产生警告,是因为我们需要在比较之前将Items集合中的项目转换回绑定到组合框的原始类型。否则,在编译器警告时,我们可能会得到意想不到的结果。

这是一个例子:

myComboBox.DataSource = Collection<Car>;

因此,如果组合框绑定到汽车对象的集合,则可以在比较之前将其回退:

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

这样一来,我们就不会收到任何警告。

我们可以执行的另一种方法是:

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

让我知道。祝你好运!我要从记忆中走出来,希望我不要输错任何内容。 :o)

第一个示例的编译警告是因为将忽略类的任何自定义==运算符,并且将比较引用(可能不是我们想要的,因此出现警告)。

无法指定应该在接口上重写运算符,因此这始终是参考比较。不需要该警告,因为我们应该始终期待这一点。

这是重写==运算符的示例:

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);
    }

}

如果Key属性相等,则将MyTest类视为相等。如果要创建接口,则不能指定它应包含自定义==运算符,因此,该比较将始终是引用比较(因此,对于我们的示例代码,为false)。