2011-03-22 17 views
17

He estado ocupado buceando en expresiones lambda recientemente, y hay algunas funcionalidades específicas que he querido aprender, pero que parecen no ser muy útiles.C# Expresiones lambda como argumentos de funciones

Supongamos que tengo la siguiente lógica en mi código:

List<A> foo; // assuming this is populated 
string[] bar = foo.Select<A,string>(x => x.StringProperty).ToArray<string>(); 

Ahora, quiero quizá abstracta que toda la operación en un método de control para que yo pueda hacer esto en su lugar:

string[] bar = MakeArray<A,string>(foo, x => x.StringProperty); 
int[] foobar = MakeArray<A,int>(foo, x => x.IntegerProperty); 

¿Qué debo hacer al escribir el cuerpo de ese método? Preveo que declara la firma como algo parecido a:

U[] MakeArray<T,U>(/* some lambda magic? */) where T : IEntity {} 

pero no sé cómo especificar que estoy esperando una expresión lambda como el argumento de método, y cómo eso se traduce exactamente en el cuerpo del método.

¿Alguien me puede mostrar cómo crear la función MakeArray() arriba? Estoy bastante seguro de que una vez que vea cómo se hace, puedo continuar desde allí.

EDITAR

Como se señaló en los comentarios, MakeArray() necesita una referencia a la IEnumerable<>. Actualizado para reflejar eso.

+5

Fwiw la naturaleza implícita de los genéricos puede agregar un valor legible a su código al no tener que indicar explícitamente el tipo con cada enunciado, aunque esto podría ser subjetivo. La siguiente declaración es igual a su primera selección .. 'cadena [] barra = foo.Select (x => x.StringProperty) .ToArray();' –

+0

Si se encuentra utilizando matrices en todo su código, es posible que desee considere refactorizarlos en 'IEnumerable ' o 'IList '. Entonces nada de esto será necesario. Además, ¿'MakeArray' no necesita una referencia a foo? –

+0

@Quintin ~ Sí, casi me gustan los genéricos explícitamente establecidos (cuando corresponda) así que está claro lo que estoy sacando. Sin embargo, estás en lo cierto. –

Respuesta

16
public static U[] MakeArray<T, U>(this IEnumerable<T> @enum, Func<T, U> rule) 
{ 
    return @enum.Select(rule).ToArray(); 
} 
+0

+1 gracias! Voy con esta respuesta para mostrar cómo se usa exactamente el parámetro Func <> que entra en el método. muy útil. –

2

Está buscando Action<> y Func<>.

13

intente lo siguiente

U[] MakeArray<T,U>(Func<T, U> projection) where T : IEntity { 
    ... 
} 

Al pasar lambdas como argumentos por lo general, desea que el parámetro de juego para ser un delegado. En la mayoría de los casos, debe usar el valor Action<> o Func<> apropiado. El primero para el vacío que devuelve lambdas y el último para los que devuelven los valores.

+0

+1 ¡gracias!Aprecio especialmente la explicación también. –

1

Puede crear extensión

public static class MakeArrayExtension 
{ 
    public static U[] MakeArray<T, U>(this IEnumerable<T> collection, Func<T,U> func) 
    { 
     return collection.Select(func).ToArray(); 
    } 
} 

y luego usarlo como esto

List<A> foo; // assuming this is populated 
string[] bar = foo.MakeArray<A,string>(x => x.StringProperty);