C # Yöntem Parametresi Olarak Lambda İfadesini Geç


106

Etrafta dolaşıp yeniden kullanmak istediğim bir lambda ifadem var. İşte kod:

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

Buradaki anahtar, burada kullandığım lambda ifadesini bu kodu çağıran yönteme geçirebilmek, böylece onu yeniden kullanabilmemdir. Lambda ifadesi .Query yöntemimin içindeki ikinci argümandır. Bir Action veya Func kullanmak isteyeceğimi varsayıyorum, ancak bunun için sözdiziminin ne olduğundan veya nasıl çalıştığından tam olarak emin değilim. Lütfen birisi bana bir örnek verebilir mi?


3
Parametreyi Action veya Func yapın.
Metro Smurf

Doğru, ben de öyle düşünmüştüm ... Bunu nasıl yapacağıma dair bir örnek gösterebilir misin?
Adam Levitt

Yanıtlar:


123

Func<T1, T2, TResult>Parametre türü olarak bir temsilci kullanın ve bunu aşağıdakilere iletin 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>();   
  }  
}

Sen buna derdin:

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

Ya da bir değişkene lambda atamak ve pas onu içinde.


Bu çok iyi görünüyor ve bu getJobs yönteminin DIŞINDA lambda'yı nasıl tanımlarım? Başka bir deyişle, lambda'yı tanımlamak için getJobs () çağrısından önceki satır nasıl görünür?
Adam Levitt

@AdamLevitt - Örnek kodunuzla aynı şekilde. Cevaba eklenecek.
2013

Ayrıca, işlev parametreleri yine de dinamik olabilir mi?
Adam Levitt

@AdamLevitt - işlevi genel yapabilirsiniz, ancak lambdalarda farklı sayıda parametre istiyorsanız, aşırı yüklemelere ihtiyacınız olacaktır.
2013

Sağ. Aslında istediğim şey, IJob arayüzünün farklı uygulamalarını geçirebilmektir, ancak bu, çalışma zamanında gerçek genel impl sınıfını gerektirdiği için Dapper's Query <> ile çalışmaz. Bu hala umduğuma oldukça yakın.
Adam Levitt

27

Anlıyorsam aşağıdaki koda ihtiyacınız var. (lambda ifadesini parametreye göre geçirme) Yöntem

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
    }

Çağrı yöntemi

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

Aynı şeyi sınıflarında da yapabilirsiniz, bunun bir örneğe bakın.

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

Çağrı yöntemi

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

Ben bunun yararlı olucağını umuyorum


2
İhtiyacımız neden açıklayabilir Compile()içinde .Where? Ben de onsuz çalıştığını gördüm.
Sнаđошƒаӽ

7

Lambda ifadelerinin bir türü vardır Action<parameters>(bir değer döndürmemeleri Func<parameters,return>durumunda ) veya (bir dönüş değerine sahip olmaları durumunda). Sizin durumunuzda iki giriş parametreniz var ve bir değer döndürmeniz gerekiyor, bu yüzden şunu kullanmalısınız:

Func<FullTimeJob, Student, FullTimeJob>

5

Bir temsilci türü kullanmalı ve bunu komut parametreniz olarak belirtmelisiniz. Yerleşik temsilci türlerinden birini kullanabilirsiniz - Actionve Func.

Sizin durumunuzda, temsilciniz iki parametre alıyor ve bir sonuç döndürüyor gibi görünüyor, böylece şunları kullanabilirsiniz Func:

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

Daha sonra GetJobsbir temsilci örneğinde geçen yönteminizi çağırabilirsiniz . Bu, bu imzayla eşleşen bir yöntem, anonim bir temsilci veya bir lambda ifadesi olabilir.

PS Yöntem adları için PascalCase kullanmalısınız - GetJobsdeğil getJobs.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.