none
Lambda expression as method parameter RRS feed

  • Question

  • Every time I think I begin to comprehend the idea of lambda expressions in C# programming, I am proven wrong.

    "The Lambda Expression in C# is the shorthand for writing the anonymous function."

    In my reading on certain development topics, I run accross numerous examples of lambda expressions passed as parameters to methods. That is almost the ONLY usage of lambda expression in my reading. I tried to write a test example. The result of my test anonymous function is type int, so I tried passing it to a method expecting an int. The error messages told me the method needs to expect a function instead.

    I tried the following, which resulted in 7 compile errors:

    private void TestLambda(Func<x, y, result> func)
    {
       string X = result.ToString();
    }
    ...
    TestLambda((a, b) => a / b);

    How do I code this correctly?

    Thanks

    Jon Jacobs, There are 10 kinds of people: those who understand binary and those who don't

    Friday, March 13, 2020 5:11 PM

Answers

  • Your TestLambda method requires that you pass it a function that accepts types X and Y and returns Result. You didn't provide the containing type so we have no way of knowing what these types are supposed to be. Let's therefore starting with fixed types and forget generics for this discussion. It doesn't change anything anyway.

    class Program
    {
        static void Main(string[] args)
        {
            //Use a normal method
            var result = TestLambda(10, 20, Add);
    
            //Use a lambda
            var result2 = TestLambda(10, 20, (x, y) => x * y);            
        }
    
        static double Add(int x, int y)
        {
            Console.WriteLine($"Add({x}, {y})");
    
            return x + y;
        }
    
        //This method requires that you pass it a function that accepts 2 ints and returns a double.        
        //x and y are provided here just so we can call the function inside the test method
        static double TestLambda ( int x, int y, Func<int, int, double> func )
        {
            return func(x, y);
        }
    }

    Lambdas are converted to private methods inside the class so they behave just like a regular method you might create as far as being able to pass them as arguments. Nothing about being a lambda changes how function arguments work.

    The only thing remotely tricky in your example is that your TestLambda wants to evaluate the argument. But to do that it needs the integral values it'll pass to that function. Hence for this test method to work you have to also include the values to pass to the function argument. Of course your TestLambda method is overkill here as you could have just as easily created a variable of the function argument type and called it directly as well.

    Func<int, int, double> func;
    
    func = Add;
    var result3 = func(10, 20);
    
    func = (x, y) => x * y;
    var result4 = func(10, 20);


    Michael Taylor http://www.michaeltaylorp3.net

    Friday, March 13, 2020 5:44 PM
    Moderator

All replies

  • Your TestLambda method requires that you pass it a function that accepts types X and Y and returns Result. You didn't provide the containing type so we have no way of knowing what these types are supposed to be. Let's therefore starting with fixed types and forget generics for this discussion. It doesn't change anything anyway.

    class Program
    {
        static void Main(string[] args)
        {
            //Use a normal method
            var result = TestLambda(10, 20, Add);
    
            //Use a lambda
            var result2 = TestLambda(10, 20, (x, y) => x * y);            
        }
    
        static double Add(int x, int y)
        {
            Console.WriteLine($"Add({x}, {y})");
    
            return x + y;
        }
    
        //This method requires that you pass it a function that accepts 2 ints and returns a double.        
        //x and y are provided here just so we can call the function inside the test method
        static double TestLambda ( int x, int y, Func<int, int, double> func )
        {
            return func(x, y);
        }
    }

    Lambdas are converted to private methods inside the class so they behave just like a regular method you might create as far as being able to pass them as arguments. Nothing about being a lambda changes how function arguments work.

    The only thing remotely tricky in your example is that your TestLambda wants to evaluate the argument. But to do that it needs the integral values it'll pass to that function. Hence for this test method to work you have to also include the values to pass to the function argument. Of course your TestLambda method is overkill here as you could have just as easily created a variable of the function argument type and called it directly as well.

    Func<int, int, double> func;
    
    func = Add;
    var result3 = func(10, 20);
    
    func = (x, y) => x * y;
    var result4 = func(10, 20);


    Michael Taylor http://www.michaeltaylorp3.net

    Friday, March 13, 2020 5:44 PM
    Moderator
  • you don't specify any types, and C# is a typed language
    And I don't understand how you expect the compiler to get the parameters into the function

    Did you mean something like this?
    Func<int, int, int> func = (a, b) => a / b;
    TestLambda<int>(func, 1, 2);
    
    private static void TestLambda<T>(Func<T, T, T> func, T a, T b)
    {
         string X = func(a, b).ToString();
    }

    Friday, March 13, 2020 6:01 PM
  • Thank you, @Michael Taylor. That works!

    I modified my code like this and it works.
    private void TestLambda(int x, int y, Func<int, int, int> func)
    {
       string X = func(x,y).ToString();
    }
    ...
    TestLambda(21,3, (a, b) => a / b);


    Jon Jacobs, There are 10 kinds of people: those who understand binary and those who don't

    Friday, March 13, 2020 6:13 PM