2013-01-12 17 views
74

Mam wyrażenie lambda, które chciałbym przekazać i wykorzystać ponownie. Oto kod:C# Pass Lambda Expression as Method Parametr

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

Kluczem tutaj jest Chcę być w stanie przekazać wyrażenie lambda że używam tutaj do metody, która dzwoni ten kod, więc mogę go ponownie wykorzystać. Wyrażenie lambda jest drugim argumentem w mojej metodzie .Query. Zakładam, że chciałbym użyć Action lub Func, ale nie jestem do końca pewien, jaka jest składnia tego lub jak działa. Czy ktoś może podać mi przykład?

+2

Dokonać parametr działania lub Func. –

+0

Tak, tak właśnie myślałem ... czy możesz pokazać mi przykład tego, jak to zrobię? –

+0

możliwy duplikat [wyrażeń C# lambda jako argumentów funkcji] (http: // stackoverflow.com/questions/5396746/c-sharp-lambda-expressions-as-function-arguments) – user

Odpowiedz

91

Użyj Func<T1, T2, TResult> delegata jako typ parametru i przekazać go do listy 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>(); 
    } 
} 

Można by to nazwać:

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

lub przypisać lambda do zmiennej i przekazać go w.

+0

To wygląda bardzo dobrze i jak zdefiniowałbym lambdę na ZEWNĄTRZ metody getJobs? Innymi słowy, jaka jest linia przed wywołaniem funkcji getJobs(), aby zdefiniować lambdę? –

+0

@AdamLevitt - W ten sam sposób, jak w przypadku przykładowego kodu. Dodam do odpowiedzi. – Oded

+0

Czy mimo to parametry funkcji mogą być dynamiczne? –

4

Wyrażenia lambdy mają typ Action<parameters> (w przypadku, gdy nie 't zwraca wartość) lub Func<parameters,return> (w przypadku, gdy mają wartość zwracaną). W twoim przypadku masz dwa parametry wejściowe i trzeba zwrócić wartość, więc należy używać:

Func<FullTimeJob, Student, FullTimeJob> 
4

Należy użyć typ delegata i określić, że jako parametr polecenia. Możesz użyć jednego z wbudowanych typów delegatów - Action i Func.

W twoim przypadku, to wygląda Twój delegat przyjmuje dwa parametry i zwraca wynik, więc można używać Func:

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

Następnie można nazwać metoda GetJobs przechodzącą w instancji delegata. Może to być metoda, która pasuje do tego podpisu, anonimowy delegat lub wyrażenie lambda.

P.S. Powinieneś używać PascalCase dla nazw metod - GetJobs, a nie getJobs.

19

Jeśli rozumiem, że potrzebujesz następującego kodu. (Przechodzącej przez parametr wyrażenie lambda) metody

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 
    } 

Wywołanie metody

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

Można zrobić to samo w swojej klasie, zobacz ten jest przykładem.

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

Wywołanie metody

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

Mam nadzieję, że jest to przydatne

+1

Czy możesz wyjaśnić, dlaczego potrzebujemy 'Compile()' w '.Where'? Widziałem, że działa bez tego. –

Powiązane problemy