0

C# で非常に単純な構造体をプログラムしました (Visual Studio 2012 と .NET 4.5 を使用しています)。

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

}

次のテストを実行して、等値演算子を使用して 2 つの異なる構造体を比較すると==:

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'. Nothing new or Interesting here が表示されます。ただし、ここで奇妙なことが起こります。私が次のことをしようとしているとしましょう:

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、 and sA.Y == sD.Y)。誰が何が起こっているのか知っていますか?

4

1 に答える 1

4

.Contains() メソッドはどのように比較を実行しますか?

文書化されているように、型のデフォルトの等値比較子を使用します。

このメソッドは、デフォルトの等値比較子を使用して等値を決定します

したがって、本質的には、次のようなものです (ただし、null 処理もあります):

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>し、不変にすることをお勧めします。

于 2013-09-20T21:32:54.307 に答える