C # Lulus Ekspresi Lambda sebagai Parameter Metode


106

Saya memiliki ekspresi lambda yang ingin saya bagikan dan gunakan kembali. Berikut kodenya:

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

Kuncinya di sini, adalah saya ingin meneruskan ekspresi lambda yang saya gunakan di sini ke dalam metode yang memanggil kode ini, jadi saya bisa menggunakannya kembali. Ekspresi lambda adalah argumen kedua di dalam metode .Query saya. Saya berasumsi saya ingin menggunakan Action atau Func, tapi saya tidak begitu yakin apa sintaksnya atau bagaimana cara kerjanya. Bisakah seseorang memberi saya contoh?


3
Jadikan parameter sebagai Action atau Func.
Metro Smurf

Benar, itulah yang saya pikirkan ... dapatkah Anda menunjukkan kepada saya contoh bagaimana saya akan melakukan ini?
Adam Levitt

Jawaban:


123

Gunakan Func<T1, T2, TResult>delegasi sebagai tipe parameter dan teruskan ke 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>();   
  }  
}

Anda akan menyebutnya:

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

Atau menetapkan lambda untuk variabel dan lulus itu di.


Ini terlihat sangat bagus, dan bagaimana saya mendefinisikan lambda DI LUAR metode getJobs ini? Dengan kata lain, seperti apa garis sebelum panggilan ke getJobs () untuk mendefinisikan lambda?
Adam Levitt

@AdamLevitt - Cara yang sama yang Anda lakukan dengan kode contoh Anda. Akan menambah jawaban.
Oded

Juga, dapatkah parameter fungsi menjadi dinamis?
Adam Levitt

@AdamLevitt - Anda dapat membuat fungsi menjadi generik, meskipun jika Anda menginginkan jumlah parameter yang berbeda pada lambda, Anda perlu kelebihan beban.
Oded

Baik. Apa yang sebenarnya saya inginkan adalah dapat meneruskan implementasi yang berbeda dari antarmuka IJob, tetapi itu tidak akan bekerja dengan Dapper's Query <> karena memerlukan kelas impl umum aktual pada waktu proses. Ini masih cukup dekat dengan apa yang saya harapkan.
Adam Levitt

27

Jika saya mengerti, Anda memerlukan kode berikut. (melewatkan ekspresi lambda dengan parameter) Metode

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
    }

Metode pemanggilan

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

Anda dapat melakukan hal yang sama di kelas mereka, lihat ini contohnya.

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

Metode pemanggilan

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

Semoga bermanfaat


2
Bisakah Anda menjelaskan mengapa kami membutuhkan Compile()di .Where? Saya telah melihat itu berhasil tanpa itu juga.
Sнаđошƒаӽ

7

Ekspresi lambda memiliki tipe Action<parameters>(jika mereka tidak mengembalikan nilai) atau Func<parameters,return>(jika mereka memiliki nilai yang dikembalikan). Dalam kasus Anda, Anda memiliki dua parameter input, dan Anda perlu mengembalikan nilai, jadi Anda harus menggunakan:

Func<FullTimeJob, Student, FullTimeJob>

5

Anda harus menggunakan tipe delegasi dan menetapkannya sebagai parameter perintah Anda. Anda dapat menggunakan salah satu tipe delegasi bawaan - Actiondan Func.

Dalam kasus Anda, sepertinya delegasi Anda mengambil dua parameter, dan mengembalikan hasil, sehingga Anda dapat menggunakan Func:

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

Anda kemudian dapat memanggil GetJobsmetode Anda dengan mengirimkan instance delegasi. Ini bisa menjadi metode yang cocok dengan tanda tangan itu, delegasi anonim, atau ekspresi lambda.

PS Anda harus menggunakan PascalCase untuk nama metode - GetJobs, bukan getJobs.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.