Dynamic delegate to pass a method as a parameter in C #

Is it possible to use DLR to refer to a method in C #?

In dynamic languages ​​like JavaScript or Python, I could easily pass a method as an argument to another method. In C #, which is a statically typed language, I either use the Delegate type, which requires a lot of casting:

 public static void AddMethod(Delegate del) { // implementation } 

and then use casting whenever I call this method

 static void Main(string[] args) { AddMethod(new Func<object, bool>(Test)); } public static bool Test(object obj) { return true; } 

Or I need to define dozens of overloads to satisfy any method calls:

 public static void AddMethod<TResult>(Func<TResult> method) { } public static void AddMethod<T, TResult>(Func<T, TResult> method) { } public static void AddMethod<T1, T2, TResult>(Func<T1, T2, TResult> method) { } public static void AddMethod<T1, T2, T3, TResult>(Func<T1, T2, T3, TResult> method) { } 

Is there a cleaner way to define an argument as a placeholder for all other methods? (I try to avoid MethodInfo or other Reflection things here)

I tried something like this:

 public delegate dynamic DynamicDelegate(params dynamic[] args); public static void AddMethod(DynamicDelegate method) { } 

But the compiler does not seem to accept a statically typed method for dynamically declared delegates!

Any other thoughts?

+4
source share
2 answers

You can use simple Action

 void AddMethod(Action action) //or void AddMethod(Func<TResult> fxn) { } 

and is called as

 AddMethod(()=>Test(obj)); 

or

 AddMethod(()=>Test(obj1,obj2)); 

- EDIT -

 AddMethod(() => Math.Max(1,3)); AddMethod(() => (int)Math.Sqrt(4)); AddMethod(() => new int[]{8,5,6}.Min()) void AddMethod(Func<int> fxn) { int i = fxn() * fxn(); // <--- } 
+2
source

Since .NET does not allow delegates with an unknown parameter syntax (this will approximate C void pointers, which is not what you want in a type language), the closest one that allows a list of variable arguments will pass an array of object arguments (t .e. object MyMethod(params object[] args)) .
However, since this array is also a reference to an object, you may need to reference a single object:

 object MyMethod(object arg)) 

The .NET Framework also does this; see for example the delegate ParameterizedThreadStart)

So, the main idea is that you require the user to write their code as a method that matches the above signature, and, in turn, it can receive any list of variable arguments of any type or size.

+2
source

Source: https://habr.com/ru/post/1448086/


All Articles