2012-01-30 10 views
14

ho bisogno di passare la query lambda come parametro, il codice seguenti è di esempio e sono interessanti per trovare un attrezzo per esso, v'è campioni: qualche cosa come questo:Esiste un modo per passare l'espressione lambda come variabile o argomento?

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

e utilizzarlo come non :

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); 
} 

Qualcuno ha un'idea a riguardo?

risposta

8

Se si definiscono le espressioni LINQ come questo:

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); 

e il metodo di UseLambda come:

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()); 
    } 
} 

Poi penso di avere quello che stai cercando.

+2

C'è un errore nel definire espr1, espr2: 'System.Collections.IEnumerable' non contiene una definizione per 'dove' e nessun metodo estensione 'Dove' accettare un primo parametro di tipo System.Collections. IEnumerable 'potrebbe essere trovato (ti manca una direttiva using o un riferimento assembly?) – Saeid

+2

bisogno di cambiare a: Func , ...... – Saeid

+0

Grazie per la modifica Saeid. – Samuel

0

Beh, un lambda non è altro che un delegato, in modo da potrebbe avere un metodo come questo:

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

Ma dov'è il senso in esso? Invece di chiamare un metodo che applica il tuo lambda, perché non chiamarlo direttamente come fai nelle ultime righe del tuo codice?

8

Verifica 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)); 
    } 
} 

Da MSDN

Il tipo sottostante di un'espressione lambda è uno dei generici Funz delegati. Ciò consente a di passare un'espressione lambda come parametro senza assegnarlo esplicitamente a un delegato. In particolare, poiché molti metodi di tipi nello spazio dei nomi System.Linq hanno parametri Func (Of T, TResult), è possibile passare questi metodi un'espressione lambda senza istanziare esplicitamente un delegato Func (Of T, TResult).

EDIT

Possibile soluzione per il vostro 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

vuoi dire qualcosa di simile:

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); 
     } 
    } 
} 

In modo che si potrebbe chiamare in questo modo:

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); 
} 
Problemi correlati