2013-01-12 21 views
74

Ho un'espressione lambda che mi piacerebbe poter passare e riutilizzare. Ecco il codice:Espressione lambda C# come parametro del metodo

public List<IJob> getJobs(/* i want to pass the lambda expr in here */) { 
    using (SqlConnection connection = new SqlConnection(getConnectionString())) { 
    connection.Open(); 
    return connection.Query<FullTimeJob, Student, FullTimeJob>(sql, 
     (job, student) => {   
     job.Student = student; 
     job.StudentId = student.Id; 
     return job; 
     }, 
     splitOn: "user_id", 
     param: parameters).ToList<IJob>(); 
    } 

La chiave qui, è che voglio essere in grado di passare l'espressione lambda che sto usando qui nel metodo che sta chiamando questo codice, in modo da poter riutilizzare. L'espressione lambda è il secondo argomento nel mio metodo .Query. Suppongo che vorrei usare un'azione o Func, ma non sono abbastanza sicuro di quale sia la sintassi per questo o di come funzioni. Qualcuno può darmi un esempio?

+2

rendere il parametro un'azione o una chiamata Func. –

+0

Giusto, questo è quello che pensavo ... puoi mostrarmi un esempio di come farei questo? –

+0

possibile duplicazione di [espressioni lambda C# come argomenti della funzione] (http: // stackoverflow.it/questions/5396746/c-sharp-lambda-expressions-as-function-arguments) – user

risposta

91

Utilizzare un delegato Func<T1, T2, TResult> come il tipo di parametro e passarlo al tuo Query:

public List<IJob> getJobs(Func<FullTimeJob, Student, FullTimeJob> lambda) 
{ 
    using (SqlConnection connection = new SqlConnection(getConnectionString())) { 
    connection.Open(); 
    return connection.Query<FullTimeJob, Student, FullTimeJob>(sql, 
     lambda, 
     splitOn: "user_id", 
     param: parameters).ToList<IJob>(); 
    } 
} 

Si potrebbe chiamare:

getJobs((job, student) => {   
     job.Student = student; 
     job.StudentId = student.Id; 
     return job; 
     }); 

o assegnare il lambda a una variabile e passare esso in.

+0

Questo sembra molto buono, e come definirei lambda OUTSIDE di questo metodo getJobs? In altre parole, qual è la linea prima che la chiamata a getJobs() assomigli a definire il lambda? –

+0

@AdamLevitt - Lo stesso modo con il codice di esempio. Aggiungerà alla risposta. – Oded

+0

Inoltre, i parametri delle funzioni possono essere comunque dinamici? –

4

espressioni Lambda hanno un tipo di Action<parameters> (nel caso in cui don 't restituire un valore) o Func<parameters,return> (nel caso in cui abbiano un valore di ritorno). Nel tuo caso si dispone di due parametri di input, ed è necessario restituire un valore, così si dovrebbe usare:

Func<FullTimeJob, Student, FullTimeJob> 
4

È necessario utilizzare un tipo di delegato e specificare che come parametro di comando. È possibile utilizzare uno dei tipi di delegati incorporati - Action e Func.

Nel tuo caso, sembra che il delegato accetta due parametri, e restituisce un risultato, così si potrebbe usare Func:

List<IJob> GetJobs(Func<FullTimeJob, Student, FullTimeJob> projection) 

È quindi possibile chiamare il metodo di GetJobs passando un'istanza delegato. Questo potrebbe essere un metodo che corrisponde a quella firma, un delegato anonimo o un'espressione lambda.

P.S. È necessario utilizzare PascalCase per i nomi dei metodi - GetJobs, non getJobs.

19

Se ho capito, è necessario il seguente codice. (Passando espressione lambda da parametro) Il Metodo

public static void Method(Expression<Func<int, bool>> predicate) { 
    int[] number={1,2,3,4,5,6,7,8,9,10}; 
    var newList = from x in number 
        .Where(predicate.Compile()) //here compile your clausuly 
        select x; 
       newList.ToList();//return a new list 
    } 

chiamata metodo

Method(v => v.Equals(1)); 

È possibile fare la stessa cosa nella loro classe, vedere questo è esempio.

public string Name {get;set;} 

public static List<Class> GetList(Expression<Func<Class, bool>> predicate) 
    { 
     List<Class> c = new List<Class>(); 
     c.Add(new Class("name1")); 
     c.Add(new Class("name2")); 

     var f = from g in c. 
       Where (predicate.Compile()) 
       select g; 
     f.ToList(); 

     return f; 
    } 

metodo

Class.GetList(c=>c.Name=="yourname"); 

Spero che questo è utile

+1

Puoi spiegare perché abbiamo bisogno di 'Compile()' in '.Where'? L'ho visto funziona anche senza questo. –

Problemi correlati