2012-01-30 18 views
14

que necesito para pasar la consulta lambda como un parámetro, el código siguientes se muestra y yo soy interesante encontrar un implemento para ello, hay muestras: algo como esto:¿Hay alguna forma de pasar la expresión lambda como una variable o argumento?

var expr1 = Where(n => n > 6).OrderBy(n => n % 2 == 0).Select(n => n); 
var expr2 = TakeWhile((n, index) => n >= index)); 

Y utilizar de esta manera :

public void UseLambda<T> (IEnumerable<T> source , lambda Expr){ 

var items= Expr.Compile(source); 

foreach(var item in items) 
    Console.Writeline(item.ToString()); 
} 

public void Main(){ 
    List<int> numbers = new List<int> { 10, 24, 9, 87, 193, 12, 7, 2, -45, -2, 9 }; 
    var expr1 = Where(n => n > 6).OrderBy(n => n % 2 == 0).Select(n => n); 
    UseLambda(numbers, expr1); 
} 

¿Alguien tiene una idea al respecto?

Respuesta

8

Si define sus expresiones LINQ como esta:

Func<IEnumerable<int>, IEnumerable<int>> expr1 = 
       l => l.Where(n => n > 6).OrderBy(n => n % 2 == 0).Select(n => n); 

Func<IEnumerable<int>, IEnumerable<int>> expr2 = 
       l => l.TakeWhile((n, index) => n >= index); 

y el método de UseLambda como:

public void UseLambda<T> (IEnumerable<T> source 
          ,Func<IEnumerable<T>, IEnumerable<T>> lambda) 
{ 
    var items= lambda(source); 

    foreach(var item in items) 
     Console.Writeline(item.ToString()); 
    } 
} 

Entonces creo que tienes lo que estás buscando.

+2

Hay un error en definir expr1, expr2: 'System.Collections.IEnumerable' no contiene una definición para y ningún método de extensión 'Dónde' aceptar un primer argumento de tipo System.Collections 'dónde''. IEnumerable 'podría encontrarse (¿falta una directiva using o una referencia de ensamblado?) – Saeid

+2

necesita cambiar a: Func , ...... – Saeid

+0

Gracias por editar Saeid. – Samuel

0

Bueno, un lambda no es más que un delegado, por lo que podría tener un método como este:

public void DoIt(IEnumerable a, Action<IEnumerable> performThis) 
{ 
    performThis(a); 
} 

Pero ¿dónde está el sentido en que? En lugar de llamar a un método que aplica su lambda, ¿por qué no llamarlo directamente como lo hace en las últimas líneas de su código?

8

Comprobar Func(Of T, TResult) Delegate (MSDN)

using System; 

public class LambdaExpression 
{ 
    public static void Main() 
    { 
     Func<string, string> convert = s => s.ToUpper(); 

     string name = "Dakota"; 
     Console.WriteLine(convert(name)); 
    } 
} 

De MSDN

El tipo subyacente de una expresión lambda es uno de los genéricos Func delegados. Esto hace que sea posible pasar una expresión lambda como parámetro sin asignarlo explícitamente a un delegado. En particular, dado que muchos métodos de tipos en el espacio de nombres System.Linq tienen parámetros Func (Of T, TResult), puede pasar estos métodos a una expresión lambda sin instanciar explícitamente un delegado Func (Of T, TResult).

EDITAR

Posible solución para su caso

static void Main(string[] args) 
{ 
    List<int> numbers = new List<int> { 10, 24, 9, 87, 193, 12, 7, 2, -45, -2, 9 }; 
    Func<IEnumerable<int>, IEnumerable<int>> expr = n => n.Where(n1 => n1 > 6).OrderBy(n1 => n1 % 2 == 0).Select(n1 => n1); 
    UseLambda<int>(numbers, expr); 
} 
private static void UseLambda<T>(List<T> numbers, 
           Func<IEnumerable<T>, 
           IEnumerable<T>> expr) 
{ 
    var values = expr(numbers); 
    foreach (var item in values) { 
     Console.WriteLine(item); 
    } 
} 
1

Qué quiere decir algo como esto:

public void UseLambda<T> (IEnumerable<T> source , Func<T, bool> where, Func<T, bool> order) 
{ 
    if(source != null) 
    { 
     IOrderedEnumerable<T> orderBy = source.Where(where).OrderBy(order); 
     foreach (T value in orderBy) 
     { 
      Console.WriteLine(value); 
     } 
    } 
} 

Para que se le puede llamar así:

UseLambda(numbers, x => x > 6, x => x % 2 == 0); 
0
public void UseLambda<T>(IEnumerable<T> source, Expression<Func<IEnumerable<T>, IEnumerable<T>>> expr) 
{ 
    var items = expr.Compile(); 

    foreach (var item in items.Invoke(source)) 
    { 
     Console.WriteLine(item.ToString()); 
    } 
} 


public void Main() 
{ 
    Expression<Func<IEnumerable<int>, IEnumerable<int>>> expr = s => s.Where(n => n > 6).OrderBy(n => n % 2 == 0).Select(n => n); 
    var list = new List<int> { 10, 24, 9, 87, 193, 12, 7, 2, -45, -2, 9 }; 

    UseLambda(list, expr); 
} 
Cuestiones relacionadas