C#ラムダ式をメソッドパラメーターとして渡す


105

渡して再利用できるようにするラムダ式があります。これがコードです:

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

ここで重要なのは、ここで使用しているラムダ式を、このコードを呼び出すメソッドに渡して、再利用できるようにすることです。ラムダ式は、.Queryメソッド内の2番目の引数です。ActionまたはFuncを使用したいと思いますが、これの構文が何であるか、またはそれがどのように機能するかはよくわかりません。誰か私に例を挙げてもらえますか?


3
パラメータをActionまたはFuncにします。
メトロスマーフ2013年

そう、それが私が思ったことです...私がこれをどうやってやるかの例を見せてくれませんか
アダムレビット2013年

回答:


122

Func<T1, T2, TResult>デリゲートをパラメータータイプとして使用し、それをyourに渡します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>();   
  }  
}

あなたはそれを呼び出すでしょう:

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

または変数にラムダを割り当て、渡すことをして。


これは非常によく見えますが、このgetJobsメソッドの外側でラムダをどのように定義しますか?言い換えると、ラムダを定義するためにgetJobs()を呼び出す前の行は何ですか?
アダムレビット2013年

@AdamLevitt-コード例と同じ方法。回答に追加します。
2013年

また、関数パラメーターはとにかく動的にすることができますか?
アダムレビット2013年

@AdamLevitt-関数をジェネリックにすることができますが、ラムダに異なる数のパラメーターが必要な場合は、オーバーロードが必要になります。
2013年

正しい。私が実際に望んでいるのは、IJobインターフェイスのさまざまな実装で渡すことができることですが、実行時に実際の汎用実装クラスを必要とするため、DapperのQuery <>では機能しません。これはまだ私が望んでいたものにかなり近いです。
アダムレビット2013年

27

私が理解した場合、次のコードが必要です。(式ラムダをパラメータで渡す)メソッド

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
    }

メソッドの呼び出し

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

クラスでも同じことができます。これは例です。

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

メソッドの呼び出し

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

これがお役に立てば幸いです


2
私たちが必要とする理由あなたは説明できますCompile().Where?それなしでも動作するのを見てきました。
Sнаđошƒаӽ

7

ラムダ式には、Action<parameters>(値を返さない場合)またはFunc<parameters,return>(戻り値がある場合)のタイプがあります。あなたのケースでは2つの入力パラメータがあり、値を返す必要があるので、以下を使用する必要があります:

Func<FullTimeJob, Student, FullTimeJob>

5

デリゲートタイプを使用し、それをコマンドパラメーターとして指定する必要があります。組み込みのデリゲート型の1つを使用できます- ActionおよびFunc

あなたの場合、デリゲートは2つのパラメーターを取り、結果を返すので、次のように使用できますFunc

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

次にGetJobs、デリゲートインスタンスを渡してメソッドを呼び出すことができます。これは、その署名に一致するメソッド、匿名のデリゲート、またはラムダ式である可能性があります。

PSメソッド名には- GetJobsではなく、PascalCaseを使用する必要がありますgetJobs

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.