3

Sometimes I encounter cases where I have to attach a method to a delegate but the signature doesn't match, like trying to attach abc down there to somedelegate with the string parameter being "hi".

public class test
{
   //...
   public void abc(int i, string x)
   {
      //Do Something
   }
   //...
}
public class test2
{
   somedelegate x;
   //...
   public test2()
   {
      //Do Something
      test y = new test();
      x += y.abc(,"hi");
   }
   delegate void somedelegate(int i);
}

I can work it around by creating another delegate with the correct signature then attaching it but it seems so unnecessarily complex. Can you do something like this in C#? Thanks.

EDIT: I guess there closest to what I wanted to achieve is:

x += (int i) => abc(i, "hi");
resgh
  • 974
  • 2
  • 12
  • 22
  • I think you should reconsider what you are trying to do. You are trying to call a method without all the required parameters? Consider all the implications of that, incorrect results, errors etc. Rather redesign your class using method overloads or implementing the [Command Pattern](http://en.wikipedia.org/wiki/Command_pattern) – shenku Feb 24 '12 at 03:01
  • This is called currying, and is extremely useful in functional programming and modular programming in general. http://stackoverflow.com/questions/36314/what-is-currying – resgh Oct 28 '16 at 18:17

2 Answers2

2

Just Googling for '.net delegate optional parameters' returns some results that may be useful:

Update (researching this some more, and helped by the first link above):

Could you perhaps use the Invoke method, which accepts any delegate?

Community
  • 1
  • 1
Peter
  • 13,733
  • 11
  • 75
  • 122
  • sorry, but im asking not about optional parameters. im trying to put a method with a different signature into a delegate by presetting some parameters when attaching – resgh Dec 30 '11 at 14:06
  • Ah, apologies. I was put off by the title of your question and thought the string parameter could be optional. Other than using optional parameters, I don't think you can achieve what you want, as that's precisely the point of delegates. – Peter Dec 30 '11 at 14:14
  • 1
    thanks for the answer. i just asked my friend and i figured i could achieve it with anonymous methods like this: x += (int i) => abc(i, "hi"); thanks anyway! – resgh Dec 30 '11 at 14:20
  • testgo, good that you've found the solution. +1 because I hadn't thought of that. Best to answer your own question now and provide a code example. This way, other developers can use this answer. Plus, it makes StackOverflow better. See this page for more info about accepting your own answers: http://blog.stackoverflow.com/2009/01/accept-your-own-answers/ – Peter Dec 30 '11 at 14:30
2

Yes, you can do this with closures

[there's a nice treatment of the subject on msdn, but like anything else in there it's hard to find]

The Big Picture

  • Write a method that can take all the parameters you need
  • Inside that method you return an anonymous method with the delegate-target signature it requires
  • This method's call is itself the parameter in the delegate instantiation

Yes, this is a bit Matrix-y. But way cool.

delegate void somedelegate (int i);

protected somedelegate DelegateSignatureAdapter ( string b, bool yesOrNo, ...) {
    // the parameters are local to this method, so we'll go w/ that.

    // our target delegate requires a single int parameter and void return
    return  (int a) => {
                // your custom code here
                // all calling arguements are in scope - use them as needed

    };  // don't forget the semicolon!
}

// our delegate call
somedelegate myWarpedDelegate = new somedelegate (DelegateSignatureAdapter("someString", true));
myWarpedDelegate (2543);
myWarpedDelegate(15);
radarbob
  • 4,964
  • 2
  • 23
  • 36
  • awesome. good one. just changed this to accepted answer. by the way, where do you get it on msdn? – resgh Dec 31 '11 at 06:56
  • This is clumsy but actually the right way, except to use anonymous functions would be much less cumbersome. – resgh Oct 28 '16 at 10:13