4

I need a C# Delegate to bind with multiple functions with different parameters first (same type) and then Fire/Invoke them later.

Please see my example below :

(Please note that my actual requirement is a lot more complex , but the same principle applies -- Don't want to bother you with the business/domain/implementation/boring bits). (Also , pardon the syntax , if its incorrect somewhere :P )

Suppose I have the following 4 functions , with the same type and number of parameters :

Void Add(int , int)
Void Subtract(int , int)
Void Multiply(int, int)
Void Divide(int , int)

I know Since they have the same parameters , I can have 1 delegate to point to all of the , correct ?

AND I Know that if i Use a multicast delegate , then I can use it to trigger all or some of them , right ?

For e.g. ,

delegate void MyDelegate (int a , int b);

And then use the delegate , something like this :-

MyDelegate del;


del = Add;

del += Subtract;
del += Multiply;

And later , I can use it like this :

del(10,20);

Now , this will fire all the functions with the same parameters 10 and 20.

My requirement is to have a multi cast delegate , where I can add up all the functions I want , but have different parameters for them.

They should not be fired/invoked when I specify the parameters, instead , they should be invoked/fired later , but altogether , and in the order then I chained/linked them.

For e.g : I want to do something like this :

delayedDelegate = Add(1,2);
//
//Some Code Here
//
delayedDelegate += Subract(3,4)

//
//Some More Code Here
//

delayedDelegate += Multiply(5,6)

//
//More Code Here
//


delayedDelegate += Add(7,8);

//
// Just a little More Code Here
//

Finally , get down to the execution :

// Fire all the chained functions with the parameters that werer assigned to them.
delayedDelegate.Invoke();     

I remember i read something of this sort , but just cant find anything by googling today. Any help would be gladly appreciated.

Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325
Uday Mehta
  • 109
  • 2
  • 13
  • 2
    Not clear. Your second sample is the same (ie all `void F(int, int)`) except for the Invoke(). The 'delayed' feature is implied, the 'variable parameters' is not possible. – H H Jul 27 '15 at 09:29
  • That is not how delegates work in C# and it looks like you have a hammer and everything looks like nails to you. You should read about Command pattern. – mswietlicki Jul 27 '15 at 09:46
  • Perhaps you are instead looking for [Tasks](https://msdn.microsoft.com/de-de/library/system.threading.tasks.task(v=vs.110).aspx)? – Sors Jul 27 '15 at 09:46
  • This will help you http://stackoverflow.com/questions/15600358/in-c-sharp-how-do-i-properly-implement-the-command-design-pattern – mswietlicki Jul 27 '15 at 09:49
  • @mswietlicki : Sorry , but I don't think I can make Command pattern work here. Maybe you could suggest , How I could use it ? – Uday Mehta Jul 27 '15 at 10:45
  • @Sors : Thanks for the suggestion to use Tasks , but then I would need to create tasks for each action and keep a reference to all of them. Since this is all being done at run time , based on the conditional evaluation , it would be impossible for me to create many tasks and keep references to all of them. Unless there is some way I could just create one and add all of them to that 1 Task ? – Uday Mehta Jul 27 '15 at 10:47
  • @Uday tasks can be chained (even conditionally) look at its methods like [ContinueWith](https://msdn.microsoft.com/en-us/library/dd270696(v=vs.110).aspx) – Sors Jul 27 '15 at 15:04
  • @Sors : Thanks for that , yes I did look a Task.ContinueWith , that would have worked just as well , probably while giving me a little more flexibility I suppose ? – Uday Mehta Aug 03 '15 at 09:09
  • @Uday absolutely correct, Tasks are a major feature of C# though mainly used for parallelism you can use them for problems like this too to make the code more readable and easier to debug – Sors Aug 03 '15 at 10:52

2 Answers2

3

The simplest solution I can think of is to use lambda expression to create closure that "converts" delegate with arbitrary parameters values to parameterless Action delegates. Add as many delegates as you want and then call them at once like this:

    //convert each delegate with parameters to Action
    Action delayedDelegate = () => Add(1, 2);
    delayedDelegate += () => Subtract(3, 4);
    delayedDelegate += () => Multiply(5, 6);

    //Later call all delegates at once
    delayedDelegate();
Ňuf
  • 6,027
  • 2
  • 23
  • 26
  • Thanks, this seems to be what I want to do , but I'm not able to use the Action keyword properly and it keeps throwing errors. Am I missing a reference or something else here ? Just need to get this to work now... Thanks for the help and Voted Up. – Uday Mehta Jul 27 '15 at 10:52
  • Action delegate is declared in mscorlib.dll in System namespace, so you should already have neccesary reference in your project. It is new class in .NET Framework 4.0, so maybe you are targeting older framework? Anyway, you can just declare it yourself as "public delegate void Action();" – Ňuf Jul 27 '15 at 11:02
  • Sorry for replying so late , this seemed to work for me , and yes , i just need to add mscorlib , I was testing this out on a small console app before plugging it into the project , so that reference wasn't there. – Uday Mehta Aug 03 '15 at 09:06
0

I'm not sure if you're looking for something like below:

public delegate int Test(int s, int j);

var o = new Test_ing();


var myDel = new Test(o.ADD);
myDel += o.Multiply;

var delegates = myDel.GetInvocationList();

var add_result = ((Test)delegates[0])(5, 6);    
var multiply_result = ((Test)delegates[1])(10, 2);

public class Test_ing
    {
        public int ADD(int i, int j)
        {
            return i + j;
        }

        public int Multiply(int i, int j)
        {
            return i * j;
        }
    }
Amit Kumar Ghosh
  • 3,618
  • 1
  • 20
  • 24