2009-09-26 10 views
8

Por lo tanto, muchas veces tenemos una función que acepta un IEnumerable o ICollection como parámetro. En los casos en los que tenemos elementos individuales, pero ninguna colección para sostenerlos, debemos crear una colección antes de pasarlos a la función, como:¿Cuál es la forma más fácil y más compacta de crear un IEnumerable <T> o ICollection <T>?

T o1, o2, o3; 
Foo(new T[] { o1, o2, o3 }); 

siempre he creado una matriz o una lista, al igual que yo' he hecho en el último ejemplo. Pero me pregunto, ¿hay una forma más elegante de crear IEnumerable o ICollection?

Sería bastante fresco, si se pudiera hacer esto:

Foo({ o1, o2, o3 }); 

Y el compilador crear la colección más abstracta posible que satisfaga las necesidades de IEnumerable o ICollection (dependiendo de lo que la función acepta)

De todos modos, ¿cómo pasaría o1, o2 y o3 a los parámetros IEnumerable o ICollection?

Respuesta

10

La versión actual de C# (3) soporta una anotación sin explícita de tipos, es decir

Foo(new [] { o1, o2, o3 }) 

para crear una matriz. También está el Enumerable.Range de Linq para crear un rango continuo de números. Todo lo demás tiene que ser implementado. En el espíritu de Java:

public static IEnumerable<T> AsList<T>(params T[] values) { 
    return values; 
} 

a ser llamados así:

Foo(Enumerable.AsList(o1, o2, o3)); 
+1

que sugieren que 'asList()' no es un buen nombre para un método que devuelve un 'Enumerable', no' list'! ¿Qué tal 'Enumerable.Create'? –

2

Suponiendo Foo espera un IEnumerable <T>, usted puede tomar ventaja de la inferencia de tipos y hacer:

T o1, o2, o3; 
Foo(new []{o1, o2, o3}); 
3

veces que he usado un método con un argumento "params".

Foo(params T[] ts) 

Y si estoy empeñado en IEnumerable Sólo tengo ese método delegado a la que quiere IEnumerable.

Foo(params T[] ts) { Foo(ts.AsEnumerable()); } 

Debes llamar a AsEnumerable o vas a recurse.

2

Crear una matriz y aprobarla es probablemente la manera más simple/más elegante de lograr esto en la versión actual de C#. Usted puede tomar ventaja de implícita escribiendo array (es decir new[] { ... }, pero eso es en lo que va

Sospecho que realmente está buscando el equivalente C# de este # Sintaxis F:.

let foo = seq [ o1; o2; o3 ] 

que genera una IEnumerable<T> que va a iterar sobre los elementos especificados. ('Sec' es en realidad el F # alias para 'IEnumerable`, aunque F # se ha incorporado en el apoyo para ellos.)

por desgracia, ya que esta es una noción ampliamente funcional, hay sin C# equivalente, aunque quién sabe cuándo se agregará, ya que C# se vuelve cada vez más divertido ctional.

0

Si tiene un método que toma una matriz como su último parámetro, puede tener sentido marcar ese parámetro params. Esto le permite llamar al método como este:

Foo(o1, o2, o3); 

Me parece especialmente útil cuando se escribe una prueba unitaria para Foo(), porque a menudo en una unidad de prueba mis parámetros son independientes de este tipo, en lugar de en una matriz.

Aconsejo que no lo haga si hay una sobrecarga de Foo() que no toma una matriz en esa posición, porque puede ser confusa rápidamente.

Me hubiera gustado que el lenguaje C# permitió params para IList<T>:

void Foo(params IList<T> ts) { ... } 
Cuestiones relacionadas