dynamic delegate to pass a method as parameter in C#
Solution 1
You can use a simple Action
void AddMethod(Action action) //or void AddMethod(Func<TResult> fxn)
{
}
and call 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(); // <---
}
Solution 2
Since .NET doesn't allow delegates with an unknown parameter syntax (this would approximate C void pointers, which is not something you want in a type-safe language), the closest thing that allows a variable argument list would be to pass an array of object arguments (i.e. object MyMethod(params object[] args))
.
However, since this array is also an object reference, you can suffice with a single object reference:
object MyMethod(object arg))
The .NET framework also does this, see e.g. the ParameterizedThreadStart delegate)
So the basic idea is that you require that the user writes his code as a method that matches the above signature, and in turn it can receive any variable list of arguments of any type or size.
![Kamyar Nazeri](https://i.stack.imgur.com/ai2jB.jpg?s=256&g=1)
Kamyar Nazeri
Coder for life with expertise in C++, C#, Python, JavaScript, TypeScript, and most recently with a focus on Cloud, Deep Learning in Computer Vision, and Generative Models. Homepage: knazeri.github.io Twitter: @knazeri LinkedIn: kamyar nazeri GitHub: github.com/knazeri
Updated on June 24, 2022Comments
-
Kamyar Nazeri about 2 years
Is there any way to use DLR to reference 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# being statically typed language, I either use
Delegate
type which needs lots 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 any cleaner way to define an argument as a placeholder for all other methods? (I'm trying to avoid
MethodInfo
or otherReflection
stuff here)I was trying something like this:
public delegate dynamic DynamicDelegate(params dynamic[] args); public static void AddMethod(DynamicDelegate method) { }
But the compiler doesn't seem to accept a statically typed method for a dynamically declared delegates!
Any other thoughts?