List <struct> .Contains()如何工作?</struct>

时间:2013-09-20 21:29:59

标签: .net

我在C#中编写了一个非常简单的结构体(我正在使用Visual Studio 2012和.NET 4.5)

public struct MyStruct
{
    public Int32 X { get; set; }
    public Int32 Y { get; set; }

}

当我执行以下测试以使用等于运算符==比较两个不同的结构时:

private void MyTest()
{
    var sA = new MyStruct() { X = 1, Y = 2 };
    var sB = new MyStruct() { X = 10, Y = 20 };

    // Expected error occurs here.
    Console.WriteLine(sA == sB ? "true" : "false");

}

我收到了预期的错误Operator '==' cannot be applied to operands of type 'MyStruct' and 'MyStruct'.这里没什么新鲜或有趣的。然而,这里的事情变得奇怪。假设我尝试执行以下操作:

private void button1_Click(object sender, EventArgs e)
{
    var sA = new MyStruct() { X = 10, Y = 10 };
    var sB = new MyStruct() { X = 20, Y = 20 };
    var sC = new MyStruct() { X = 30, Y = 30 };
    var sD = new MyStruct() { X = 10, Y = 10 };

    // Note that struct sD contains the same data as sA.

    var myList = new List<MyStruct>();

    myList.Add(sA);
    myList.Add(sB);

    // This line writes "true" to the console window.
    Console.WriteLine(myList.Contains(sA) ? "true" : "false");

    // This line writes "true" to the console window.
    Console.WriteLine(myList.Contains(sB) ? "true" : "false");

    // This line writes "false" to the console window.
    Console.WriteLine(myList.Contains(sC) ? "true" : "false");

    // This line writes "true" to the console window.
    Console.WriteLine(myList.Contains(sD) ? "true" : "false");

}

.Contains()方法如何执行比较?它显然没有比较参考,因为它表明sD在列表中。它似乎进入结构并按属性比较它们(例如sA.X == sD.XsA.Y == sD.Y)。有谁知道发生了什么?

1 个答案:

答案 0 :(得分:4)

  

.Contains()方法如何执行比较?

它使用类型的默认相等比较器,如documented

  

此方法使用默认的相等比较器

确定相等性

基本上,这样的东西(但也处理空值):

var comparer = EqualityComparer<T>.Default;
foreach (var item in this)
{
    if (comparer.Equals(item, target))
    {
        return true;
    }
}
return false;

EqualityComparer<MyStruct>.Default只会对字段执行简单的比较,但我会建议您自己覆盖Equals并在结构上实现IEquatable<T> - 并使其不可变。