2010-03-29 11 views
12

Estoy usando un Dictionary<int, MyType> en una clase. Esa clase implementa una interfaz que requiere que se devuelva IList<MyType>. ¿Hay una manera simple de lanzar el uno al otro (sin copiar todo el asunto)?Convertir diccionario <MyType> .ValueCollection a IList <MyType>

Mi solución actual sigue:

private IList<MyType> ConvertToList(Dictionary<int, MyType>.ValueCollection valueCollection) 
{ 
    List<MyType> list = new List<MyType>(); 
    list.AddRange(valueCollection); 
    return list; 
} 
+0

Cada solución publicada hasta el momento implica copiar toda la colección. **Lea la pregunta**. – SLaks

+0

@SLaks: me dirigí a esto directamente en mi respuesta ... (que todavía implica la copia, sin embargo) –

+0

¿Hay alguna relevancia para el tipo de clave "int", o es un tipo arbitrario? –

Respuesta

20

Tendrá que hacer una copia, pero esto probablemente sea algo bueno. En C# 2, tu código actual es casi el más limpio que puedes hacer. Se mejoraría al construir directamente la lista de sus valores (List<MyType> list = new List<MyType>(valueCollection);), pero aún se requerirá una copia.

mediante LINQ con C# 3, sin embargo, que sería capaz de hacer:

myDictionary.Values.ToList(); 

Dicho esto, yo no (probablemente) tratar de evitar la copia. Devolver una copia de sus valores tiende a ser más seguro, ya que evita que la persona que llama cause problemas si intentan modificar su colección. Al devolver una copia, la persona que llama puede hacer list.Add(...) o list.Remove(...) sin causar problemas en su clase.


Editar: Teniendo en cuenta su comentario a continuación, si lo que quieres es un IEnumerable<T> con un conde, sólo puede volver ICollection<T>. Este se directamente ejecutados por ValueCollection, lo que significa que sólo puede devolver valores de su diccionario directamente, sin copiar:

private ICollection<MyType> ConvertToList(Dictionary<int, MyType>.ValueCollection valueCollection) 
{ 
    return valueCollection; 
} 

(Por supuesto, este método se convierte realmente inútil en este caso - pero quería demostrar que para usted ...)

+0

@Slaks: De ahí la siguiente frase: "Puede construir directamente su lista de sus valores";) Eso no es mucho mejor, aunque como es una ICollection , será más eficiente (ya que se conoce el recuento de antemano). –

+0

@Slaks: ¿Eso es mejor? Lo hice más explícito. –

+0

Gracias por la excelente respuesta. La interfaz ICollection se ajusta perfectamente a mis necesidades. –

0

Puede utilizar el constructor: (. Editado para eliminar una afirmación que no estoy 100% seguro de)

public IList<MyType> MyValues 
{ 
    get { return new List<MyType>(myDictionary.Values); } 
} 

+0

Esto aún crea una copia de la colección. – mcNux

4

Cómo sobre

Dictionary<int, MyType> dlist = new Dictionary<int, MyType>(); 
IList<MyType> list = new List<MyType>(dlist.Values); 
+2

Esto todavía copia la colección. – SLaks

2

Esto no es posible.

Un diccionario (incluida su colección Values) es una colección inherentemente desordenada; su orden cambiará en función de los códigos de hash de sus claves. Es por eso que ValueCollection no implementa IList<T> en primer lugar.

Si realmente quisiera, podría hacer una clase de contenedor que implementa IList y envuelve el ValueCollection, usando un bucle foreach en el indexador. Sin embargo, no es una buena idea.

+0

@SLaks No soy exigente con el pedido. Lo que quiero es IEnumerable con un conteo. Si hay una interfaz mejor, házmelo saber. –

+0

@C. Ross: mira mi edición, entonces ... –

Cuestiones relacionadas