2011-07-14 3 views
11

LINQPadに付属するlinqサンプルのいくつかを驚いていました。 Chater 9 - Groupingの下にある "C#3.0 in a Nutshell"フォルダには、 "Multiple Keys Grouping"というサンプルクエリがあります。これは、以下のクエリが含まれていますVB.NET linq group by匿名の型が期待どおりに機能しない

from n in new[] { "Tom", "Dick", "Harry", "Mary", "Jay" }.AsQueryable() 
group n by new 
{ 
    FirstLetter = n[0], 
    Length = n.Length 
} 

私は、実際のグループ化を取得するために、配列の末尾に文字列「ジョン」を追加し、以下の結果を思い付いた:

C# LINQPad result

このまさに私が期待していたものでした。一緒にしないの適切グループジェイ/ジョン

' Manually added "Jon" 
from n in new string() { "Tom", "Dick", "Harry", "Mary", "Jay", "Jon" }.AsQueryable() _ 
group by ng = new with _ 
{ _ 
    .FirstLetter = n(0), _ 
    .Length = n.Length _ 
} into group 

結果を:次に、LINQPadに、私は同じクエリのVB.NET版に行ってきました。

VB.NET LINQPad result

ビットのために私の髪を引っ張った後、私はVB.NET匿名型を議論this MSDN articleを発見しました。 VB.NETでは、デフォルトで変更可能ですが、C#では不変です。 VBでは、Keyキーワードを追加して不変にする必要があります。だから、私は(Keyのほかに気づく)これにクエリを変更:

    :だから私の質問はこれです

    enter image description here

    from n in new string() { "Tom", "Dick", "Harry", "Mary", "Jay", "Jon" }.AsQueryable() _ 
    group by ng = new with _ 
    { _ 
        Key .FirstLetter = n(0), _ 
        Key .Length = n.Length _ 
    } into group 
    

    これは私に正しい結果を与えました

  1. linqが等価比較を行うときに、匿名型の可変性/不変性が問題になるのはなぜですか?特に、Linq-to-SQLでは、それはまったく重要ではありません。これはおそらくSQLへの翻訳の単なる製品です。しかし、Linqからオブジェクトへは、明らかにすべての違いがあります。
  2. なぜMSはVBの匿名型を変更可能にするのですか?私は本当の利点はないと思っています。そして、この問題をぶち壊した後、私はいくつかの本当の欠点を見ます。つまり、linqのクエリに微妙なバグがある可能性があります。

- EDIT -

情報のジャスト面白い余分な部分...どうやらこれは鍵付きプロパティの問題では広く知られています。私はちょうどGoogleに何を知らなかった。 stackoverflowでherehereが議論されています。ここでは匿名型と個別を使用して、問題の別の例です:

Dim items = New String() {"a", "b", "b", "c", "c", "c"} 
Dim result = items.Select(Function(x) New With {.MyValue = x}).Distinct() 
Dim result2 = items.Select(Function(x) New With {Key .MyValue = x}).Distinct() 
'Debug.Assert(result.Count() = 3) ' Nope... it's 6! 
Debug.Assert(result2.Count() = 3) 
+1

ありがとうございました!私はこの問題を1年以上にわたって解決してきました。この奇妙な問題を解決するために、すべてのグループ化コードが荒廃しています。私はちょうどこの問題を示すためにサンプルをノックし、治療法を見つけようとしましたが、これは解決策のようです。 「Key」キーワードを追加することが解決策です。私はpastebinのコードをここに入れました:http://pastebin.com/pa7KjZv2 – Tom

答えて

11

Key修飾子はちょうど可変性には影響しません - それはまた、EqualsGetHashCodeの動作に影響を与えます。これらの計算には、Keyプロパティのみが含まれています...グループ化などには明らかに影響します。

VBとは異なる理由は分かりません。私にとっても奇妙に思える。私は知っている私はだとうれしいC#はそれがやっているように動作します:)それでも、それはデフォルトにする必要がありますが表示されませんを変更することができます。

関連する問題