C# Pass Lambda Expression as Method Parameter

C#LinqLambda

C# Problem Overview


I have a lambda expression that I'd like to be able to pass around and reuse. Here's the code:

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

The key here, is I want to be able to pass the lambda expression that I'm using here into the method that's calling this code, so I can reuse it. The lambda expression is the second argument inside my .Query method. I'm assuming I'd want to use an Action or Func, but I'm not quite sure what the syntax is for this or how it quite works. Can someone please give me an example?

C# Solutions


Solution 1 - C#

Use a Func<T1, T2, TResult> delegate as the parameter type and pass it in to 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>();   
  }  
}

You would call it:

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

Or assign the lambda to a variable and pass it in.

Solution 2 - C#

If I understand you need following code. (passing expression lambda by parameter) The Method

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
    }

Calling method

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

You can do the same in their class, see this is example.

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

Calling method

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

I hope this is useful

Solution 3 - C#

Lambda expressions have a type of Action<parameters> (in case they don't return a value) or Func<parameters,return> (in case they have a return value). In your case you have two input parameters, and you need to return a value, so you should use:

Func<FullTimeJob, Student, FullTimeJob>

Solution 4 - C#

You should use a delegate type and specify that as your command parameter. You could use one of the built in delegate types - Action and Func.

In your case, it looks like your delegate takes two parameters, and returns a result, so you could use Func:

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

You could then call your GetJobs method passing in a delegate instance. This could be a method which matches that signature, an anonymous delegate, or a lambda expression.

P.S. You should use PascalCase for method names - GetJobs, not getJobs.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAdam LevittView Question on Stackoverflow
Solution 1 - C#OdedView Answer on Stackoverflow
Solution 2 - C#MarinpietriView Answer on Stackoverflow
Solution 3 - C#SztupYView Answer on Stackoverflow
Solution 4 - C#devdigitalView Answer on Stackoverflow