2011-12-14 3 views
17

Я пытаюсь создать службу служб данных служб WCF, которая группируется на стороне сервера, а затем отправляет данные клиенту.Что такое реализующий класс для IGrouping?

Когда я пытаюсь позвонить (или даже подключиться к сервису), я получаю сообщение об ошибке. В нем говорится, что он не может построить интерфейс.

Единственный интерфейс, который я использую, - это группировка.

Что является фактическим классом для этого интерфейса?


Update:

Я проверил тип при отладке приложения образца и сказал мне, что это было:

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

Но что сборка он в?

+0

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

+0

WCF Services Data ServiceOperation? Или операция WCF? – Jeff

+0

System.Core имеет все реализации LINQ. – Jeff

ответ

24

Несколько типов в реализации BCL IGrouping, однако все они являются внутренними и не могут быть доступны, кроме как через интерфейс IGrouping.

Но IGrouping - это всего лишь IEnumerable<TElement> с ассоциированным ключом. Вы можете легко реализовать IGrouping, что подкреплено List<TElement> и что не должно быть трудно сериализовать через границу вызова:

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(); } 

} 

После применения оператора GroupBy вы можете создать список Grouping экземпляров:

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, нет общественного типа в рамках .NET ядра, который реализует System.Linq.IGrouping<TKey,TElement>. Если вам нужен такой тип (скажем, это сериализуемый), вам, вероятно, придется, к сожалению, набросить его самостоятельно.

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(); 
    } 
} 
Смежные вопросы