我在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.X
和sA.Y == sD.Y
)。有谁知道发生了什么?
答案 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>
- 并使其不可变。