2011-07-25 9 views
19

Tengo un método que devuelve ILookup. En algunos casos, quiero devolver un ILookup vacío como una salida anticipada. ¿Cuál es la mejor manera de construir un ILookup vacío?Empty ILookup <K, T>

+0

¿Qué tipo es usted usando como K y T en su ILookup ? –

Respuesta

37

Además de las respuestas de mquander y Vasile Bujac, puede crear una clase de EmptyLookup<K,E> sencilla, simple y simple como sigue. (En mi opinión, hay no parece mucho beneficio para la creación de un ILookup<K,E> aplicación plena de acuerdo con la respuesta de Vasile.)

var empty = EmptyLookup<int, string>.Instance; 

// ... 

public static class EmptyLookup<TKey, TElement> 
{ 
    private static readonly ILookup<TKey, TElement> _instance 
     = Enumerable.Empty<TElement>().ToLookup(x => default(TKey)); 

    public static ILookup<TKey, TElement> Instance 
    { 
     get { return _instance; } 
    } 
} 
+0

Gracias a mquander y Vasile pero creo que esta fusión de las dos soluciones es la más simple/mejor. –

-1

Usted puede volver nula

o excepción

Pero debe tener en cuenta que en el comentario de la clase

Agregado: + Esto es más evidente que algún método de extensión

+4

Estoy totalmente en desacuerdo. Si una función devuelve un mapa de búsqueda de algunos 'K's a' T's, y sucede que no hay 'K's o' T's, es obvio que la función debe devolver una búsqueda vacía. No tiene sentido devolver nulo o lanzar una excepción, y de repente tener que buscarlo en todas partes, cuando hubiera salido de la caja si hubiera devuelto una búsqueda vacía. – mquander

+0

"ILookup como salida anticipada": este es un caso típico en el que debe lanzar una excepción. –

+0

Si coloca la excepción de comentario abreviado, todos los demás desarrolladores lo ven con estilo. Y procesa esa excepción. –

18

No hay Built-in , entonces solo escribiría un método de extensión que ejecute algo similar a new T[0].ToLookup<K, T>(x => default(K));

I es muy dudoso que devolver nulo sería más correcto aquí. Casi nunca se da el caso de que desee devolver el valor nulo de un método que devuelve una colección (a diferencia de una colección vacía). No podría estar más en desacuerdo con las personas que sugieren eso.

+0

Se debe considerar la semántica del valor de retorno. Por ejemplo, una búsqueda que no devuelve resultados debe devolver una colección vacía, pero una búsqueda que ha fallado (por ejemplo) o que tenía parámetros no válidos debería devolver 'null'. –

+3

Bueno, una búsqueda que tiene parámetros no válidos (como en, argumentos inválidos para un método, supongo) probablemente debería arrojar. Pero entiendo tu significado. Sin embargo, es muy común que un método devuelva una colección vacía, y sería un desastre devolver nulo en ese caso. – mquander

+0

Usted es de hecho correcto con respecto a tirar al error. Sin embargo, he trabajado con aplicaciones comerciales donde, por ejemplo, ciertos sistemas externos no estarían disponibles durante ciertas horas del día; en tales casos, las consultas y las solicitudes fallarían, pero no es un caso "excepcional", ya que era el comportamiento esperado. –

7

Puede crear una clase singleton para búsquedas vacías.

public sealed class EmptyLookup<T, K> : ILookup<T, K> 
{ 
     private static readonly EmptyLookup<T, K> _instance 
      = new EmptyLookup<T, K>(); 

     public static EmptyLookup<T, K> Instance 
     { 
      get { return _instance; } 
     } 

     private EmptyLookup() { } 

     public bool Contains(T key) 
     { 
      return false; 
     } 

     public int Count 
     { 
      get { return 0; } 
     } 

     public IEnumerable<K> this[T key] 
     { 
      get { return Enumerable.Empty<K>(); } 
     } 

     public IEnumerator<IGrouping<T, K>> GetEnumerator() 
     { 
      yield break; 
     } 

     System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 
     { 
      yield break; 
     } 
    } 

entonces se puede escribir código como este:

var x = EmptyLookup<int, int>.Instance; 

La ventaja de crear una nueva clase es que se puede utilizar el "es" operador y comprobar el tipo de igualdad:

if (x is EmptyLookup<,>) { 
// .... 
} 
+0

Esta es probablemente la mejor respuesta, estrictamente hablando. – mquander

+0

Gracias, se ve bien. Sugeriría que [] arroje KeyNotFoundException en lugar de NotImplementedException. –

+0

Sí, tienes razón, gracias. He editado mi publicación – Vasea

1

Cree una lista vacía, luego ejecute ToLookup() en ella, como este:

List<Point> items = new List<Point>(); 
ILookup<int, int> lookup = items.ToLookup(p => p.X, p => p.Y); 

¡Buena suerte!

-1

O algo más en el espíritu de LINQ:

public static class Utility 
{ 

    public static ILookup<TKey, TElement> EmptyLookup<TKey, TElement>(Func<TKey, TKey> keySelector, 
                     Func<TKey, TElement> elementSelector) 
    { 
     return Enumerable.Empty<TKey>().ToLookup(keySelector, elementSelector); 
    } 

} 
+0

¿Por qué molestarse en tomar los funcs de los selectores? –

Cuestiones relacionadas