2011-11-28 17 views
7

Solo por curiosidad, ¿por qué llamar a IEnumerable.ToList() en una Lista existente no devuelve la misma instancia? Lo mismo se aplica a IEnuerable.ToArray(). ¿No sería esto mejor desde el punto de vista del consumo de memoria?.NET ¿Por qué IEnumerable.ToList() en una Lista existente crea una nueva matriz

que corrieron la siguiente prueba rápida:

var things= new List<Thing>(new [] {new Thing(), new Thing()}); 
     Console.WriteLine(things.GetHashCode()); 

     things= things.ToList(); 
     Console.WriteLine(things.GetHashCode()); 

y consigo diferentes instancias de objetos. ¿Por qué no simplemente las mismas instancias?

Respuesta

9

Esto se hace intencionadamente para habilitar el escenario "copiar lista".

Por ejemplo, si hago foreach(var a in list) list.Remove(a), obtendré una excepción diciendo que "la colección ha sido modificada" mientras la enumeración estaba en progreso.

Para solucionar esto, hago: foreach(var a in list.ToList()) list.Remove(a).

Si desea la semántica en la línea de "convertir a la lista si no es una ya", tendrá que manejarlo usted mismo. De hecho, en realidad se podría escribir un método de extensión ordenada para esto:

public static IList<T> ToListIfNotAlready(this IEnumerable<T> source) 
{ 
    var list = source as IList<T>; 
    return list == null ? source.ToList() : list; 
} 

Sí, podría haber sido al revés, pero los diseñadores de LINQ eligió este enfoque, y tenía todo el derecho a hacerlo, ya que ni enfoque tiene una ventaja clara en el caso general.

+0

Me gusta la extensión, gracias. –

1

Como no se puede modificar el contenido de una enumeración mientras se está enumerando, hay momentos en los que necesita crear una copia de la lista para poder repetir una copia y modificar la otra. ToList() se define como la devolución de una nueva lista que es independiente de la lista original.

0

Comportamiento de ToList() no tiene nada que ver con la enumeración. Hace lo que su nombre implica, es decir, devuelve una lista. No implica que devuelva la misma lista con cada llamada; de otra manera; la instancia de la lista debería almacenarse internamente en alguna parte. Lo mismo con muchas otras funciones Linq. El hecho de que devuelva una nueva lista es beneficioso para usar con el enumerador de foreach.

Cuestiones relacionadas