1

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

在 WinForms 项目中,如果我使用该行

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

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

但是,如果我改为使用接口进行比较:

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

编译警告消失了。

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

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

就好像编译器只是假设我绑定到 IMyInterface 列表。

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

4

2 回答 2

1

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

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

这是覆盖 == 运算符的示例:

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)。

于 2008-10-04T21:46:45.630 回答
0

拉格达莱克,

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

这是一个例子:

myComboBox.DataSource = Collection<Car>;

因此,如果组合框绑定到汽车对象的集合,您将在比较之前将它们回退:

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

那么你不应该得到任何警告。

您可以做的另一种方法是:

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

让我知道。祝你好运!我从记忆中走出来,希望我没有打错任何东西。:o)

于 2008-09-19T01:39:26.670 回答