I have a list object like so
private List<Func<int, double, char, string, string>> FuncList;
And have been attempting to add items to this list using delegates and anonymous functions. The problem is, when I attempt to make a function that has this type, I must return a function from that function. I'm managed to do this recursively, but this throws it into an infinite loop. Is it possible to add functions to this list, and if so how?
I'm attempting to add functions that are passed into a delegate like so
public delegate Func<int, double, char, string, string> funcDelegate(someFunc);
And then do something like this
FuncList.add(funcDelegate);
How would you write someFunc so that this code would work.
My failed attempt at writing a function that returns the correct type is like so, this does not work as it's recursive with no stopping case.
public Func<int, double, char, string, string> SomeFunc(int i, double d, char c, string s1, string s2)
{
Console.WriteLine($"{i}\n{d}\n{c}\n{s1}\n{s2}");
return this.SomeFunc(i,d,c,s1,s2);
}
First, your method doesn't have the right signature. The last generic parameter in Func<> is the return type. Action<> is a generic delegate type that returns void.
Second, the whole point of using Func<> is that you DON'T need to create new types of delegates - Func<> is already a delegate.
Here's an example:
// A list of delegates that accept an integer and return a string
private static List<Func<int, string>> delegateList = new List<Func<int, string>>();
public static string Foo(int x)
{
return $"Foo {x}";
}
public static void Test()
{
delegateList.Add(Foo); // Add a delegate to a named method
delegateList.Add(delegate(int x) { return $"Bar {x * 2}"; } ); // Add a delegate to an anonymous method
delegateList.Add(x => $"Baz {x * 3}"); // Add a delegate to a lambda
foreach (var del in delegateList)
{
Console.WriteLine(del(23));
}
}
In your example, you are declaring a delegate to a function that returns another delegate, but that doesn't seem to be what you're trying to accomplish.
Here's my two cent's worth - it handles arbitrary delegates with up to 4 input parameters, but can be extended ...
public class so40645583
{
private IList<Delegate> FuncList = new List<Delegate>();
public void Add<InputType, OutputType>(Func<InputType, OutputType> func)
{
FuncList.Add(func);
}
public void Add<InT1, InT2, OutputType>(Func<InT1, InT2, OutputType> func)
{
FuncList.Add(func);
}
public void Add<InT1, InT2, InT3, OutputType>(Func<InT1, InT2, InT3, OutputType> func)
{
FuncList.Add(func);
}
public void Add<InT1, InT2, InT3, InT4, OutputType>(Func<InT1, InT2, InT3, InT4, OutputType> func)
{
FuncList.Add(func);
}
// This won't work as it is trying to return a delegate type
// public static Func<int, double, char, string, string> SomeFunc(int i, double d, char c, string s1)
public static string SomeFunc(int i, double d, char c, string s1)
{
return String.Format("{0} {1} {2} {3}", i, d, c, s1);
}
public static string SomeFunc2(int i)
{
return i.ToString();
}
public void Test()
{
Add<int, double, char, string, string>(SomeFunc);
Add<int, string>(SomeFunc2);
// Try invoking via list
Delegate d = FuncList[0];
string s = (string)d.DynamicInvoke(2, 2.0, 'c', "Hi");
Console.WriteLine(s);
// Invoke directly
s = SomeFunc(2, 2.0, 'c', "Hi");
Console.WriteLine(s);
// Now the second one
d = FuncList[1];
s = (string)d.DynamicInvoke(5);
Console.WriteLine(s);
}
}
To run the test:
var so = new so40645583();
so.Test();
Related
This question already has answers here:
Why can't C# infer type from this seemingly simple, obvious case
(5 answers)
Closed 7 years ago.
A colleague wrote this extension method that I wanted to produce an example for:
namespace ExtensionMethods {
public static class MyExtensions {
public static Res MyAggregate<T, Res>(this IEnumerable<T> source, Func<Res, int, T, Res> f) {
var i = 0;
Res result = default(Res);
foreach (T x in source) {
result = f(result, i, x);
i++;
}
return result;
}
}
}
It creates a generic Aggregate method that also includes an index.
My example (that follows) takes a list of strings and joins the 1st letter from the first word, the 2nd from the second, etc..
namespace ExtensionMethods {
public class Program {
public static string OffsetChars(string x, int i, string y) {
return x + y[i];
}
static void Main(string[] args) {
List<string> test = new List<string>() { "hello", "there", "you" };
// get h from (h)ello, h from t(h)ere and u from yo(u) (hhu)
string result = test.MyAggregate<string, string>(OffsetChars);
Console.WriteLine(result);
Console.ReadKey();
}
}
}
My question is about this line (the important one):
string result = test.MyAggregate<string, string>(OffsetChars);
Without <string, string> there is an error that the types of arguments cannot be inferred from usage. My question(s):
Why cannot they be inferred? Is there something missing from my code that would enable them to be inferred?
I tested with an explicit delegate (follows) but the same error occurs:
namespace ExtensionMethods {
delegate string OffsetMethod(string x, int i, string y);
public class Program {
public static string OffsetChars(string x, int i, string y) {
return x + y[i];
}
static void Main(string[] args) {
List<string> test = new List<string>() { "hello", "there", "you" };
// get h from (h)ello, h from t(h)ere and u from yo(u) (hhu)
OffsetMethod myMethod = OffsetChars;
string result = test.MyAggregate(myMethod);
Console.WriteLine(result);
Console.ReadKey();
}
}
}
To summarize, I want to ensure that I haven't missed anything with my code and, assuming that I haven't, to understand why the parameter types cannot be inferred.
Your method is just a delegate and therefore does not have any generic type arguments that could be infered.
When you define OffsetChars as a generic Func, they can be infered just fine:
public static Func<string, int, string, string> OffsetChars = (x, i, y) =>
{
return x + y[i];
};
WERTZUI is right, because the delegate does not have any generic arguments, compiler cannot infer it, so you have se error.
I have a client application that uses classes (and enums) from an external dll which is loaded at runtime and reflected. I know what methods I am expecting to find in the dll and what I am expecting its enums to be called.
I would like to create a delegate that I can use in the client application and which is created from the reflected method at runtime. This approach works when the delegate just has "standard" types, but how can I get this to work if the dll method takes an enum? I can't declare the enum in the delegate as an object since it's a value type, trying the Enum or int does not seem to work either. Is there a way around this? Any help gratefully received!
// e.g. external code
namespace test2
{
public static class test2
{
public static int calc(int a, int b, testEnum c)
{
if (c == testEnum.add) return a + b;
else return a - b;
}
public static int add(int a, int b)
{
return a + b;
}
}
public enum testEnum
{
add, subtract
}
}
// my client code
namespace test1
{
public class TestClient
{
private static Assembly _assembly;
public static void SetUp()
{
const string externalDll = ".../test2.dll";
Assembly assembly = Assembly.LoadFrom(externalDll);
AppDomain.CurrentDomain.Load(assembly.GetName());
_assembly = assembly;
}
private delegate int _add(int a, int b);
private _add add;
private delegate int _calc(int a, int b, ??? c); // nothing works here
private _calc calc;
public void Run()
{
SetUp();
add = GetExpectedFunction<_add>("add");
int three = add(1, 2); // OK
calc = GetExpectedFunction<_calc>("calc"); // not OK
// intended usage
var reflectedEnum = ReflectMe("testEnum", "add");
int threeAgain = calc(1, 2, reflectedEnum);
}
public static T GetExpectedFunction<T>(string functionName) where T : class
{
try
{
if (!typeof(T).IsSubclassOf(typeof(Delegate))) throw new ApplicationException("GetExpectedFunction must return a delegate!");
var foundMethod = _assembly.GetType("test2.test2").GetMethod(functionName, BindingFlags.Public | BindingFlags.Static);
return (T)(object)Delegate.CreateDelegate(typeof(T), foundMethod);
}
catch (Exception e)
{
// "Error binding to target method!"
}
}
}
}
You can bind a delegate with object type to a method taking an enum by creating, at runtime, a dynamic method call with LINQ Expression, and adding data conversions for parameters whose types don't match:
public static T GetExpectedFunction<T>(string functionName) where T : class {
try {
if (!typeof(T).IsSubclassOf(typeof(Delegate))) throw new ApplicationException("GetExpectedFunction must return a delegate!");
var foundMethod = Type.GetType("test2.test2").GetMethod(functionName, BindingFlags.Public | BindingFlags.Static);
var inv = typeof(T).GetMethod("Invoke");
var parameters = inv.GetParameters().Zip(foundMethod.GetParameters(), (a, b) => new {
PassedIn = a.ParameterType
, Reflected = b.ParameterType
, Parameter = Expression.Parameter(a.ParameterType)
}).ToList();
if (parameters.All(p => p.PassedIn == p.Reflected)) {
// Bind directly
return (T)(object)Delegate.CreateDelegate(typeof(T), foundMethod);
}
var call = Expression.Call(foundMethod, parameters.Select(
p => p.PassedIn==p.Reflected
? (Expression)p.Parameter
: Expression.Convert(p.Parameter, p.Reflected)
));
return (T) (object) Expression.Lambda(typeof(T), call, parameters.Select(p => p.Parameter)).Compile();
} catch (Exception e) {
// "Error binding to target method!"
return null;
}
}
This implementation pairs up types from the reflected and the delegate methods (see parameters variable), and creates ParameterExpression objects for types that come from the delegate. Then it checks if all parameter types match up (the parameters.All(...) part). This is an optimization for situations when conversions are unnecessary.
If at least one conversion is necessary, the code creates a method call that substitutes the original parameter expressions with conversion expressions where types do not match up, creates a lambda of the requested delegate type, compiles it, and returns it to the caller.
For your code this dynamic method would look like this:
int dynamic_method(int a, int b, object c) {
return test2.test2(a, b, (testEnum)c);
}
There is one solution, you have to create faked Enum (it will be better if you create the exact enum), then you will pass as integer like this:
private delegate int _add(int a, int b);
private _add add;
private delegate int _calc(int a, int b, FakedEnum c); // faked enum here
private _calc calc;
public enum FakedEnum
{
}
public void Run()
{
SetUp();
add = GetExpectedFunction<_add>("add");
int three = add(1, 2); // OK
calc = GetExpectedFunction<_calc>("calc"); // it will be ok
var result= calc(4, 6, (FakedEnum)0);
// intended usage
// var reflectedEnum = ReflectMe("testEnum", "add");
//int threeAgain = calc(1, 2, reflectedEnum);
}
Use dynamic keyword to declare your delegate parameter:
private delegate int _calc(int a, int b, dynamic c);
I need to give the possibility to add any method returning double and taking any amount of double parameters to the Dictionary. Help me please.
class Program
{
Dictionary<string, Delegate> _functions;
static double MyFunc (double x, double y, double z, double q, double r, double t)
{
return 100;
}
// and the user can create his functions with any amount of parameters
static void AddFunction (Delegate d)
{
_functions.Add (d.Method.Name, d);
}
static void Main (string [] args)
{
_functions = new Dictionary<string, Delegate> ();
Program.AddFunction(MyFunc);
}
}
Well, I'm not sure how you plan on exactly calling this. Since you have a variable number of inputs, you can treat them like an array input.
delegate double MyDictionaryDelegate(params double[] input);
static Dictionary<string, MyDictionaryDelegate> _functions;
static void AddFunction (MyDictionaryDelegate d)
{
_functions.Add(d.Method.Name, d);
}
But then this essentially turns your called functions into handling collections (with any of the benefits/limitations this implies):
public static double MyFunc (params double[] input)
{
return input.Sum();
}
So your usage might be like:
_functions = new Dictionary<string, MyDictionaryDelegate> ();
AddFunction(MyFunc);
Console.WriteLine(_functions["MyFunc"](1, 2.5, 0));//3.5
But I suspect you'd rather keep the original list of parameter arguments rather than a list, something like this:
public static double AnotherFunc(double x, double y, double z)
{
return x + y + z;
}
You could simply have a wrapper function:
public static double AnotherFunc(params double[] input)
{
//preferably with some check that the proper number of
//input parameters are included
return AnotherFuncImpl(input[0], input[1], input[2]);
}
But this seems overall kind of dangerous to me; I'm not sure I'd recommend it.
EDIT: Here's another option to avoid the param double[] input arrays and always have fixed parameter arguments. Use the Delegate as you had, but you'd have to use its DynamicInvoke. In addition, you'd declare several AddFunction overloads for each number of parameters you expect to reasonably have:
static Dictionary<string, Delegate> _functions;
private static void AddFunction (string functionName, Delegate d)
{
_functions.Add(functionName, d);
}
private static void AddFunction(Func<double> d)
{
_functions.Add(d.Method.Name, d);
}
private static void AddFunction(Func<double, double> d)
{
_functions.Add(d.Method.Name, d);
}
private static void AddFunction(Func<double, double, double> d)
{
_functions.Add(d.Method.Name, d);
}
private static void AddFunction(Func<double, double, double, double> d)
{
_functions.Add(d.Method.Name, d);
}
//additional overloads up to N parameters
Then usage might be:
public static double MyFunc(double x, double y, double z)
{
return x + y + z;
}
_functions = new Dictionary<string, Delegate> ();
AddFunction(MyFunc);
Console.WriteLine(_functions["MyFunc"].DynamicInvoke(1, 2.5, 0));//3.5
But once again, this can fail if the caller did not properly call DynamicInvoke with the exact number of required parameters (no more, no less).
I still feel as though overall, whatever it is you're doing would benefit from a different design.
Define a new class object that has the delegate and the parameter list you require, then the dictionary<string, clsObject> would be how you define the dictionary.
Cast the method as a Func<T1, T2, .., TResult> when you add it to the collection:
Program.AddFunction(
(Func<double, double, double, double, double, double, double>)MyFunc);
You need to declare your delegate as returning a double, and taking a param of doubles, here is a full working example.
public class Widget
{
// declares a delegate called AddDelegate that takes a param of doubles
public delegate double AddDelegate(params double[] dbls);
Dictionary<string, AddDelegate> functions;
public Widget()
{
functions = new Dictionary<string, AddDelegate>();
}
public void Add(AddDelegate d)
{
functions.Add(d.Method.Name, d);
}
public void Run()
{
foreach (var kvp in functions)
{
// write out the name and result of each function added to our list
Console.Write(kvp.Key);
Console.Write(": ");
Console.Write(kvp.Value(10.0, 10.0, 10.0, 10.0));
}
}
}
class Program
{
static double CalcDouble(params double[] dbls)
{
double total = 0.0;
foreach (double d in dbls)
{
total += d;
}
return total;
}
static void Main(string[] args)
{
var w = new Widget();
w.Add(new Widget.AddDelegate(CalcDouble));
w.Run();
}
}
Do you mean defining a delegate with the params modifier on its arguments? The answer is apparently no, because the compiler converts the additional arguments to an array in a method call, but not for delegates. See the link for some solutions.
I have code:
public delegate int SomeDelegate(int p);
public static int Inc(int p) {
return p + 1;
}
I can cast Inc to SomeDelegate or Func<int, int>:
SomeDelegate a = Inc;
Func<int, int> b = Inc;
but I can't cast Inc to SomeDelegate and after that cast to Func<int, int> with usual way like this:
Func<int, int> c = (Func<int, int>)a; // Сompilation error
How I can do it?
There's a much simpler way to do it, which all the other answers have missed:
Func<int, int> c = a.Invoke;
See this blog post for more info.
SomeDelegate a = Inc;
Func<int, int> b = Inc;
is short for
SomeDelegate a = new SomeDelegate(Inc); // no cast here
Func<int, int> b = new Func<int, int>(Inc);
You can't cast an instance of SomeDelegate to a Func<int, int> for the same reason you can't cast a string to a Dictionary<int, int> -- they're different types.
This works:
Func<int, int> c = x => a(x);
which is syntactic sugar for
class MyLambda
{
SomeDelegate a;
public MyLambda(SomeDelegate a) { this.a = a; }
public int Invoke(int x) { return this.a(x); }
}
Func<int, int> c = new Func<int, int>(new MyLambda(a).Invoke);
Try this:
Func<int, int> c = (Func<int, int>)Delegate.CreateDelegate(typeof(Func<int, int>),
b.Target,
b.Method);
The problem is that:
SomeDelegate a = Inc;
Isn't actually a cast. It's the short-form of:
SomeDelegate a = new SomeDelegate(Inc);
Therefore there's no cast. A simple solution to your problem can be this (in C# 3.0)
Func<int,int> f = i=>a(i);
This works (in C# 4.0 at least - not tried in earlier versions):
SomeDelegate a = Inc;
Func<int, int> c = new Func<int, int>(a);
If you look at the IL, this compiles into exactly the same code as Winston's answer. Here's the IL for the second line of what I just wrote:
ldloc.0
ldftn instance int32 ConsoleApplication1.Program/SomeDelegate::Invoke(int32)
newobj instance void class [mscorlib]System.Func`2<int32,int32>::.ctor(object, native int)
And that's also precisely what you see if you assign a.Invoke into c.
Incidentally, although Diego's solution is more efficient, in that the resulting delegate refers directly to the underlying method rather than going through the other delegate, it doesn't handle multicast delegates correctly. Winston's solution does, because it just defers completely to the other delegate. If you want a direct solution that also handles delegates with multiple targets, you need something a little more complex:
public static TResult DuplicateDelegateAs<TResult>(MulticastDelegate source)
{
Delegate result = null;
foreach (Delegate sourceItem in source.GetInvocationList())
{
var copy = Delegate.CreateDelegate(
typeof(TResult), sourceItem.Target, sourceItem.Method);
result = Delegate.Combine(result, copy);
}
return (TResult) (object) result;
}
This does the right thing for delegates with a single target by the way—it will end up producing just a single delegate of the target type that refers directly to whatever method (and where applicable, object) the input delegate referred to.
You can hack a cast by using a trick where you use the c# equivalent of a c++ union. The tricky part is the struct with two members that have a [FieldOffset(0)]:
[TestFixture]
public class Demo
{
public void print(int i)
{
Console.WriteLine("Int: "+i);
}
private delegate void mydelegate(int i);
[StructLayout(LayoutKind.Explicit)]
struct funky
{
[FieldOffset(0)]
public mydelegate a;
[FieldOffset(0)]
public System.Action<int> b;
}
[Test]
public void delegatetest()
{
System.Action<int> f = print;
funky myfunky;
myfunky.a = null;
myfunky.b = f;
mydelegate a = myfunky.a;
a(5);
}
}
It is the same kind of problem as this:
public delegate int SomeDelegate1(int p);
public delegate int SomeDelegate2(int p);
...
SomeDelegate1 a = new SomeDelegate1(Inc);
SomeDelegate2 b = (SomeDelegate2)a; // CS0030
which is the same kind of problem as:
public class A { int prop { get; set; } }
public class B { int prop { get; set; } }
...
A obja = new A();
B objb = (B)obja; // CS0029
Objects cannot be casted from one type to an unrelated other type, even though the types are otherwise completely compatible. For lack of a better term: an object has type identity that it carries along at runtime. That identity cannot be changed after the object is created. The visible manifestation of this identity is Object.GetType().
I like examples. Here is my example code:
class Program
{
class A
{
public A(D d) { d.Invoke("I'm A!"); }
public delegate string D(string s);
}
class B
{
public delegate string D(string s);
}
static void Main(string[] args)
{
//1. Func to delegates
string F(dynamic s) { Console.WriteLine(s); return s; }
Func<string, string> f = F;
//new A(f);//Error CS1503 Argument 1: cannot convert from 'System.Func<string, string>' to 'ConsoleApp3.Program.A.D'
new A(new A.D(f));//I'm A!
new A(x=>f(x));//I'm A!
Func<string, string> f2 = s => { Console.WriteLine(s); return s; };
//new A(f2);//Same as A(f)
new A(new A.D(f2));//I'm A!
new A(x => f2(x));//I'm A!
//You can even convert between delegate types
new A(new A.D(new B.D(f)));//I'm A!
//2. delegate to F
A.D d = s => { Console.WriteLine(s); return s; };
Func<string, string> f3 = d.Invoke;
f3("I'm f3!");//I'm f3!
Func<string, string> f4 = new Func<string, string>(d);
f4("I'm f4!");//I'm f4!
Console.ReadLine();
}
}
The output is:
Is it possible to pass a function as a parameter in C#? I can do it using the Func or Action classes, but this forces me to declare the entire function signature at once. When I try to use Delegate, I get a compile error saying it can't convert a method group to a Delegate.
I'm working on Axial and I'm trying to allow users to call web services. What I'm going for is the ability to create the Visual Studio proxy class and then pass in the generated function. The function signature doesn't matter because the generated code only uses the function name. However, I'd like to pass in the function instead of the name for two reasons: the ability to use the proxy's Url property and a compiler error if the web service doesn't exist or is updated in Visual Studio.
public void AlertIt(object o) {
Axial.DOM.Window.Alert(o.ToString());
}
public void CallAddService() {
object[] param = new object[] { int.Parse(txtA.Text), int.Parse(txtB.Text) };
Axial.ServerScript.CallWebService(new WSProxy.WS().Add, param, AlertIt, AlertIt);
}
class Axial.ServerScript {
public void CallWebService(Delegate method, object[] param, Action<object> successCallback, Action<object> failureCallback) {
// translate to javascript (already working)
}
}
I think what you want is:
static object InvokeMethod(Delegate method, params object[] args){
return method.DynamicInvoke(args);
}
static int Add(int a, int b){
return a + b;
}
static void Test(){
Console.WriteLine(InvokeMethod(new Func<int, int, int>(Add), 5, 4));
}
Prints "9".
Converting a method group, anonymous method or lambda expression to a delegate requires the compiler to know the exact delegate type. However, you could potentially use lambda expressions and captured variables to make this simpler:
public void InvokeMethod(Action action)
{
action();
}
public int Add(int a, int b)
{
return a + b;
}
public void Test()
{
InvokeMethod(() => Add(2, 3));
}
That basically delays invocation in the normal way, but by wrapping the actual call to Add in a plain Action delegate.
If that doesn't fulfil your requirements, perhaps you can tell us a bit more about what you're really trying to achieve.
EDIT: If this is generated code, you can cast to a Func<...> with the right type arguments - assuming there aren't too many. Other than that, there's no real way of just passing in a method group. There's been occasional calls for an "infoof(...)" operator (like typeof but for members) which would give you a MemberInfo, but that doesn't actually exist.
You should have a delegate first
delegate int Operation(int a, int b)
then it becomes:
public void InvokeMethod(Operation method, object target, object param)
{
method((int) target, (int) param);
}
No need for any call to Invoke.
As with dbone I'm unsure why you would need a params[] array. Would you clarify the expanded usage for the params?
Also, I'll have to correct something in your question though, because it will cause a compilation error :p
please have a look at using delegates here is a great example
Delegate Example
why are you using reflection? will there ever be a different number of params? or do you know the method signture will remain constant (also remember C# supports the params[] keyword)
params c#
HTH
Bones
Look at Functional Programming Series by Justin Etheredge.
You should find solution to your problem there.
This is much simple example, to programmer who already familiar with (C/C++/VB.NET/Python)-style pass function by pointer/ref (with C# delegate):
delegate void CALLBACK(String s);
static void Main(string[] args)
{
Get("some string", testfunc);
Util.pause();
}
static void Get(String s, CALLBACK x)
{
x(s);
}
static void testfunc(String s)
{
Console.WriteLine(s);
}
Say If you need to pass the method as parameter as well as you need to catch the return value for further processing . Then the above examples will work fine .
But say if you need to pass a method with void return type then you need to create one more version of the InvokeMethod function.
Check the example below.
private static T retry<T>(Delegate method, params object[] args)
{
for (int i = 0; i <= 3; i++)
{
try
{
return (T)method.DynamicInvoke(args);
}
catch (Exception ex)
{
if (i == 3)
{
logMessage(ex.Message);
}
Console.WriteLine("Retry count " + i);
Thread.Sleep(10);
}
}
return default(T);
}
private static void retry2(Delegate method, params object[] args)
{
for (int i = 0; i <= 3; i++)
{
try
{
method.DynamicInvoke(args);
break;
}
catch (Exception ex)
{
if (i == 3)
{
logMessage(ex.Message);
//return default(T);
}
Console.WriteLine("Retry count " + i);
Thread.Sleep(10);
}
}
}
static bool isSuccess = true;
static void logMessage(string msg)
{
isSuccess = false;
Console.WriteLine(msg);
}
static int Add(int a, int b)
{
return a + b;
}
static void Add2(int a, int b)
{
int c = a + b;
Console.WriteLine(c);
}
static void Main(string[] args)
{
int d = retry<int>(new Func<int, int, int>(Add), 6, 7.7);
Console.Write(" " + d + "\n"+isSuccess);
retry2(new Action<int, int>(Add2), 45, 60);
Console.ReadKey();
}
Something like this ought to work for you:
delegate int MyDelegate(int a, int b);
public int Add(int a, int b) {
return a + b;
}
public void InvokeMethod(Delegate method, object[] param) {
Console.WriteLine(method.DynamicInvoke(param));
}
public Form1() {
InitializeComponent();
InvokeMethod(new MyDelegate(Add), new object[] { 1, 2 });
}
Good luck!