Pass action delegate as parameter in C#
Asked Answered
H

4

13

I have a method which accepts an Action delegate and executes the given method as shown here:

public void ExpMethod(Action inputDel)
{
    inpuDel();
}

I can call above given method like this:

ExpMethod(() => {/*do something that matters*/});

Everything works fine. So far so good. Now I want to have a method which takes a generic Action delegate as an input parameter - like this:

public void ExpGenMethod(Action<string,int> inputDel)
{
    // I don't know how to call the supplied delegate as it requires parameters
}

Also, I am trying to call this ExpGenMethod in this way:

ExpGenMethod(("Hi",1) => {/*do something that makes sense*/});

But it shows syntax errors. Please let me know how to use generic action delegate in this case?

Hailee answered 26/1, 2017 at 9:4 Comment(3)
If the caller is supplying "input", the input should be absorbed into the body of the lambda, not as parameters - so your existing method should still work and "Hi" and 1 wouldn't be on the left of the =>.Flexuous
What error do you get? Please show the exact message.Corrianne
Does this answer your question? Pass Method as Parameter using C#Roseola
C
20

The whole point of a delegate is to have a pointer to a method. Passing parameters to it while it´s being declared is therefor pointless. Instead pass the arguments for your delegate within the method that executes the delegate, in your case within ExpGenMethod:

You should do this instead:

public void ExpGenMethod(Action<string,int> inputDel)
{
    inputDel("Hi", 1);
}

And call it like this:

ExpGenMethod((x, y) => {/*do something that makes sense*/});

When executing that delegate x evaluates to "Hi" and y to 1.

Corrianne answered 26/1, 2017 at 9:10 Comment(2)
Are you expecting the parameters to be "Hi", 1 always ?Thomsen
@VinodSrivastav Of course not. Those values shpuld be computed by whatever code - either within that method or via args passed to it. The point of the answer just was the param-values are not part of the delegate. Instead they are passed to it.Corrianne
P
7

Typically, you'll want the heavy lifting to happen in the ExpGenMethod and in the delegate itself you'll simply be passing the parameters to the ExpGenMethod.

using System;

public class Program
{
    public static void Main()
    {
        ExpGenMethod((options) =>
        {
            options.x = "Hi";
            options.y = 1;
        });
    }

    public static void ExpGenMethod(Action<Options> inputDel)
    {
        var options = new Options();
        inputDel(options);
        /* have access to x and y so do some thing useful with these values */
        Console.WriteLine(options.x);
        Console.WriteLine(options.y);
    }
}

public class Options
{
    public string x { set; get;}

    public int y { set; get; }
}

Panathenaea answered 9/12, 2020 at 4:0 Comment(2)
Well appreciated answer, @Sangeet you save my time.Kulun
Thanks. Could you please tell me what is the advantage of abstracting away the x and y arguments into an Options class, and then passing said Options instance using a Lambda function?Stroller
S
6

(a,b) => {/*do something that matters*/} means that a and b are parameters which are going to be specified during the call. Here you are using constant so you should do something like () => { use "Hi"; use 1;} and that would get you back to your first working example.

If you want to pass parameter you cna do it this way:

public void work()
{
    ExpGenMethod((a) => {/*do something that matters*/});
}

public void ExpGenMethod(Action<int> inputDel, int parameterToUse)
{
    inputDel(parameterToUse);
}
Storeroom answered 26/1, 2017 at 9:12 Comment(0)
C
0

As a follow on to what @HimBromBeere explained:

The keyword Action is defined as delegate:

public delegate void Action<in T1, in T2>(T1 arg1, T2 arg2);

So if the method is defined as:

public void ExpGenMethod(Action<string,int> inputDel)
{
    inputDel("Hi", 1);
}

You can call ExpGenMethod with parameters x,y is using a Lambda expression, and see the results using Console.Writeline as follows:

ExpGenMethod((x, y) => { Console.WriteLine($"{x} {y}"); });
Catanzaro answered 3/5, 2021 at 17:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.