2011-12-14 32 views
17

Estoy intentando crear un servicio de servicios WCF DataOperation que agrupa en el lado del servidor y luego envía los datos al cliente.¿Cuál es la clase de implementación para IGrouping?

Cuando intento llamarlo (o incluso conectarme al servicio) aparece un error. Dice que no puede construir una interfaz.

La única interfaz que estoy usando es IGrouping.

¿Cuál es la clase real de esta interfaz?


Actualización:

he comprobado el tipo mientras se depura una aplicación de ejemplo y me dijeron que era:

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

Pero lo que el montaje es en?

+0

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

+0

WCF Data Services ServiceOperation? O la operación WCF? – Jeff

+0

System.Core tiene todas las implementaciones de LINQ. – Jeff

Respuesta

24

Varios tipos en el implemento BCL IGrouping, sin embargo, todos son internos y no se puede acceder a ellos, excepto por la interfaz IGrouping.

Pero un IGrouping es simplemente un IEnumerable<TElement> con una clave asociada. Se puede implementar fácilmente un IGrouping que está respaldado por un List<TElement> y que no debe ser difícil para serializar través de un límite de llamadas:

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

} 

Después de aplicar el operador GroupBy puede crear una lista de Grouping casos:

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

Probablemente el enfoque más fácil sería algo así como: var newGrouping = new List () .GroupBy (t => t.MyKey); – aBetterGamer

+1

@aBetterGamer: Creo que la pregunta no es sobre cómo crear un 'IGrouping', que es bastante fácil, como se señala, sino cómo recrear" algo "que implementa' IGrouping' en el otro lado de un límite de serialización. –

4

I comprueba el tipo con una aplicación de ejemplo y es esta: System.Linq.Lookup<TKey,TElement>.Grouping. ¿Pero en qué ensamblaje se encuentra?

Es un tipo anidado en System.Linq.Lookup<TKey,TElement>; interno al ensamblaje 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); 

de salida:

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

A partir de .NET 4.0, no hay ningún tipo público en el marco .NET núcleo que implementa System.Linq.IGrouping<TKey,TElement>. Si necesita ese tipo (digamos que es serializable), es probable que tenga que lanzar uno usted mismo, desafortunadamente.

9

Aquí está probablemente la implementación más básica y genérica de IGrouping. Su constructor toma una clave y un conjunto de valores.

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