3

次のように定義されたクラスがあるとします。

public class DataHolder
{
    public string PropA { get; set; }
    public string PropB { get; set; }
    public string PropC { get; set; }
    public int PropD { get; set; }
}

DataHolder次のように宣言された s の配列のインスタンスがあります。

    var x=new DataHolder[]{
        new DataHolder(){PropA="A",PropB="X",PropC="J",PropD=1},
        new DataHolder(){PropA="A",PropB="Y",PropC="J",PropD=3},
        new DataHolder(){PropA="A",PropB="Y",PropC="J",PropD=5},
        new DataHolder(){PropA="B",PropB="X",PropC="K",PropD=7},
        new DataHolder(){PropA="B",PropB="Y",PropC="L",PropD=9},
        new DataHolder(){PropA="C",PropB="X",PropC="J",PropD=11},
        new DataHolder(){PropA="C",PropB="X",PropC="J",PropD=13},
        new DataHolder(){PropA="C",PropB="Y",PropC="J",PropD=15},
        new DataHolder(){PropA="C",PropB="Z",PropC="J",PropD=17}
    };

そして、次のように LINQ GroupBy クエリを実行します。

    var t = x.GroupBy(c => new { A = c.PropA, B = c.PropB, C = c.PropC })

結果を調べると、t には 7 つの要素があることがわかります。これは、配列内の異なる PropA、PropB、PropC の組み合わせの数であり、これが私が求めている効果です (イェイ!)。しかし、匿名型の新しい各インスタンスは他のインスタンスと等しくなく、t には 9 つの要素が必要なため、実際には機能しないはずだと思いました。最初に思ったように機能するのはなぜですか?

4

2 に答える 2

7

匿名型の場合:

匿名型の Equals および GetHashCode メソッドは、プロパティの Equals および GetHashcode メソッドに関して定義されるため、同じ匿名型の 2 つのインスタンスが等しいのは、それらのすべてのプロパティが等しい場合のみです。

( MSDNから取得)

Equalsそのため、「正常な」プロパティごとの比較を行うオーバーロードがあります。

于 2013-08-21T07:47:31.760 に答える
6

次の両方が true の場合、2 つの匿名型は「等しい」ことに注意してください。

1) 彼らは同じタイプです

( MSDN :「アセンブリ内の 2 つ以上の匿名オブジェクト初期化子が、同じ順序で同じ名前と型を持つ一連のプロパティを指定する場合、コンパイラはオブジェクトを同じ型のインスタンスとして扱います。それらは同じを共有します。コンパイラによって生成された型情報。")

2) すべてのプロパティが等しい。

ここでは「同じ順序」が重要であることに注意してください。

var a = new {A = 1, B = "Dog"};
var b = new {A = 1, B = "Dog"};
var c = new {B = "Dog", A = 1};

a.Equals(b) // true
a.Equals(c) // false -- a and c are instances of different types.
于 2013-08-21T08:16:09.027 に答える