2

My objective is demostrated with the following code:

void MyMethod<T>(T aMethod, params object[] aParams) where T: System.Delegate
{
    aMethod.Invoke(aParams);
}

How can I do this kind of thing?

Max
  • 19,654
  • 13
  • 84
  • 122

3 Answers3

2

You could use Unconstrained Melody - or pinch the bit which allows this.

On the other hand, that's not actually going to expose an Invoke method anyway. What do you want to do which can't be done with:

void MyMethod(Delegate aMethod, params object[] aParams)
{
    aMethod.DynamicInvoke(aParams);
}

? I mean, you wouldn't actually have compile-time safety even with the generic version, as the parameters could be of the wrong types etc.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • I was hoping to get parameter type safety somehow. – Max Dec 07 '10 at 22:14
  • @Max: Why not just invoke the method directly then? I don't see what this is really buying you. – Jon Skeet Dec 07 '10 at 22:23
  • I want to extract common exception handling code. try { invoke } catch(1) {} catch(2) {} ... – Max Dec 07 '10 at 23:37
  • One situation where a generic constraint would be helpful would be writing a type-safe delegate-combining extension method versions of `Delegate.Combine` and `Delegate.Remove` (given `Action Act1` and `ActionAct2`, it would be nice if `Act1.Plus(Act2)` could yield an `Action` containing both delegates (converting the second delegate if need be). I can't figure out a way to have the method know the compile-time type of `Act1` without having Intellisense offer the `Plus` method on arbitrary class objects. – supercat Dec 14 '12 at 21:00
  • @supercat: Yup, I think Unconstrained Melody could do that... – Jon Skeet Dec 15 '12 at 08:08
1

I'm not sure what you're actually trying to accomplish: Since only the compiler or runtime can inherit from System.Delegate, what point does the generic have over:

void MyMethod<T>(System.Delegate aMethod, params object[] aParams) 
{
  aMethod.DynamicInvoke(aParams);
}

Now, if you're trying to do something tricky with delegate type constraints, you can look at http://code.google.com/p/unconstrained-melody/ , which does some il rewriting to allow you to do it.

Or, just use an Action<object[]> - or lots of overloads with Action<T>, Action<T1,T2>, etc.

void MyMethod(Action<object[]> aMethod, params object[] aParams)
{
   aMethod(aParams);
} 

//or
void MyMethod<T>(Action<T> aMethod, T param)
{
   aMethod(param);
} 

void MyMethod<T1, T2>(Action<T1, T2> aMethod, T1 param1, T2 param2)
{
   aMethod(param1, param2);
} 

I don't really like the huge list of overloads, but in some cases they provide the best library usability.

Philip Rieck
  • 32,368
  • 11
  • 87
  • 99
0

T must be a type, but you don't need any generics

void MyMethod(Action<object[]> aMethod, params object[] aParams)
{
    aMethod(aParams);
}

void Print(params object[] output)
{
    foreach (var o in output)
        Console.WriteLine(o);
}

call it like this:

MyMethod(Print, 1, "Hello");
Albin Sunnanbo
  • 46,430
  • 8
  • 69
  • 108