2011-12-14 18 views
17

私は、サーバー側でグループ化し、クライアントにデータを送信するWCF Data Services ServiceOperationを作成しようとしています。IGroupingの実装クラスは何ですか?

私はそれを呼び出すとき(またはサービスに接続するとき)にエラーが発生します。それは、それがインタフェースを構築することはできないと言います。

私が使用しているインターフェイスはIGroupingだけです。

このインターフェイスの実際のクラスとは何ですか?


更新:

サンプルアプリケーションのデバッグ中に、私は種類をチェックし、それはそれがあった私に言った:

System.Linq.Lookup<TKey,TElement>.Grouping 

しかし、どのようなアセンブリは、それがでているのですか?

+0

はhttp://stackoverflow.com/questions/5072955/is-it-possible-to-create-some-igrouping-object – ChrisF

+0

WCF Data ServicesのServiceOperationを参照してください?またはWCF操作ですか? – Jeff

+0

System.CoreにはすべてのLINQ実装があります。 – Jeff

答えて

24

BCLのいくつかのタイプはIGroupingを実装していますが、すべて内部であり、IGroupingインターフェイス以外ではアクセスできません。

ただし、IGroupingは、関連付けられたキーを持つIEnumerable<TElement>です。あなたは簡単にList<TElement>によって支えられてIGroupingを実装することができ、それはコール境界を越えてシリアライズするために難しいことではありません:あなたはGroupingインスタンスのリストを作成することができGroupByオペレータを適用した後

public class Grouping<TKey, TElement> : IGrouping<TKey, TElement> { 

    readonly List<TElement> elements; 

    public Grouping(IGrouping<TKey, TElement> grouping) { 
    if (grouping == null) 
     throw new ArgumentNullException("grouping"); 
    Key = grouping.Key; 
    elements = grouping.ToList(); 
    } 

    public TKey Key { get; private set; } 

    public IEnumerator<TElement> GetEnumerator() { 
    return this.elements.GetEnumerator(); 
    } 

    IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } 

} 

var listOfGroups = 
    source.GroupBy(x => ...).Select(g => new Grouping<TKey, TElement>(g)).ToList(); 
+2

おそらく最も簡単なアプローチは次のようなものです:var newGrouping = new List ().GroupBy(t => t.MyKey); – aBetterGamer

+1

@aBetterGamer:あなたが指摘しているように非常に簡単なIGroupingを作成する方法ではなく、直列化境界の反対側でIGroupingを実装する「何か」を再作成する方法が問題だと思います。 –

4

私は、サンプルアプリでタイプをチェックし、それはこれです:System.Linq.Lookup<TKey,TElement>.Grouping。しかし、それはどのような組み立てですか?

System.Linq.Lookup<TKey,TElement>にネストされたタイプです。組立体内のSystem.Coreの内部にある。

var groupingType = "1".GroupBy(x => x).Single().GetType().GetGenericTypeDefinition(); 
Console.WriteLine("Type: " + groupingType); 
Console.WriteLine("Public: " + groupingType.IsPublic); 
Console.WriteLine("Assembly: " + groupingType.Assembly); 

出力:

Type: System.Linq.Lookup`2+Grouping[TKey,TElement] 
Public: False 
Assembly: System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 

.NET 4.0のように、System.Linq.IGrouping<TKey,TElement>を実装コア.NETフレームワークにはパブリック型は存在しません。そのような型(シリアライズ可能なもの)が必要な場合は、残念なことにおそらく自分自身をロールバックする必要があります。

9

おそらくIGroupingの最も基本的で一般的な実装です。そのコンストラクタは、キーと値のセットを取ります。

public class Grouping<TKey, TElement> : IGrouping<TKey, TElement> 
{ 
    private readonly TKey key; 
    private readonly IEnumerable<TElement> values; 

    public Grouping(TKey key, IEnumerable<TElement> values) 
    { 
     if (values == null) 
      throw new ArgumentNullException("values"); 
     this.key = key; 
     this.values = values; 
    } 

    public TKey Key 
    { 
     get { return key; } 
    } 

    public IEnumerator<TElement> GetEnumerator() 
    { 
     return values.GetEnumerator(); 
    } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return GetEnumerator(); 
    } 
}