2011-05-20 14 views
21

Estoy buscando una manera fácil de clonar un parámetro IEnumerable<T> para referencia futura. El método de extensión ToArray de LINQ parece una forma agradable y concisa de hacer esto.¿Puedo confiar en que LINQ ToArray() siempre devuelve una nueva instancia?

Sin embargo, no tengo claro si siempre se garantiza que devolverá una nueva instancia de matriz. Varios de los métodos LINQ verificarán el tipo real del enumerable y el acceso directo si es posible; por ejemplo, Count() verá si el método implementa ICollection<T>, y si es así, leerá directamente su propiedad Count; solo itera la colección si es necesario.

Dado que la mentalidad de un cortocircuito cuando sea práctico, parece que, si llamo ToArray() en algo que ya es una matriz, ToArray() podría cortocircuito y devuelva la misma instancia de matriz. Eso cumpliría técnicamente los requisitos de un método ToArray.

Desde una prueba rápida, parece que, en .NET 4.0, llamando ToArray() en una serie hace devolver una nueva instancia. Mi pregunta es: ¿puedo confiar en esto? ¿Se puede garantizar que ToArray siempre devolverá una nueva instancia, incluso en Silverlight y en versiones futuras de .NET Framework? ¿Hay alguna documentación que sea clara en este punto?

Respuesta

25

Sí, ToArray siempre devolverá una nueva matriz - hacer que cambie para devolver un valor existente sería un cambio horrible, y estoy absolutamente convencido de que el equipo .NET no haría esto. Es algo importante en lo que puedes confiar. Es una pena que no está documentado :(

Hay un montón de sutiles bits de comportamiento en LINQ a objetos que probablemente no vale la pena confiar en, pero en este caso es un masiva poco de comportamiento tal, sería absolutamente asombrado de que cambie.

el cortocircuito es grande cuando no afecta al comportamiento, pero en general LINQ a objetos es bastante bueno sobre la optimización solamente en casos válidos. es posible que desee ver el twoposts en mi serie Edulinq que cubre la optimización.

15

Dado que el método ToArray es interno al .NET framework, no apostaría mi vida por MS nunca lo cambiaría. Sin embargo, lo que haría, es agregar una prueba de unidad que afirme que ToArray devuelve una nueva instancia de matriz.

Assert.AreNotSame(myArray, myArray.ToArray()); 

esta manera, si posteriormente cambia versiones del marco .NET, automáticamente se sabe si los cambios de funcionalidad.

+0

+1 para la idea de prueba de la unidad. – NerdFury

Cuestiones relacionadas