How do I make an anonymous method take a variable number of arguments?
I would like to be able to make inline calls to anonymous methods with a variable number of arguments (sometimes no arguments, sometimes 11).
Dictionary<string, Action> ActionDic = new Dictionary<string, Action>();
int i = 0;
ActionDic["something"] = () => { i += 1; }; // this line is ok
ActionDic["somethingArgs"] = (int n) => { n += 1; }; // but this is not
// Delegate 'System.Action' does not take 1 arguments
Therefore, I cannot get the delegate to accept such arguments. Is my syntax wrong, or is it just not possible? Or do I need to change the type of the anonymous method that I should be using for my dictionary?
source to share
You can use Action<int>
if you want to define a delegate with 1 integer argument. For example:
Action<int> somethingArgs = (int n) => { n += 1; };
You haven't specified what a variable is ActionDic
, but if it is IDictionary<string, Action>
, you can't make the job because it Action
doesn't take an argument.
Alternatively, you can use a delegate dictionary:
IDictionary<string, Delegate> ActionDic = ...
ActionDic["something"] = (Action)(() => { i += 1; });
ActionDic["somethingArgs"] = (Action<int>)((int n) => { n += 1; });
source to share
You can not. Action
and Action<T>
- different, incompatible types of delegates.
There are several ways to compensate for this.
One could make ActionDic
a Dictionary<string, Action<int>>
, but it can not satisfy all potential delegates that you want to use.
Others would do ActionDic
something like Dictionary<string, Delegate>
, but that would be cumbersome to use because you need to know exactly how many many parameters (and their types) to pass to each function. This information needs to be stored in another data structure somewhere.
Another third way is to do ActionDic
a Dictionary<string, Action<object[]>>
and ask the delegate to unpack all the arguments it needs. The caller is responsible for knowing exactly what arguments to use. This will allow the somewhat less awkward syntax of the second option, but requires more code in each delegate.
source to share
You are talking about two different delegates i.e. Action
and Action<T>
. You cannot assign Action<T>
to Action
:
Action a1 = () => { i += 1; };
Action<int> a2 = (n) => { n += 1; };
I assume you have Dictionary<string,Action>
, so this dictionary cannot accept a value Action<T>
.
As a side note, I would say that the second delegate is completely useless, since it increments the argument int
passed by value, which actually does nothing.
Also consider reading How to Pass Optional Arguments . While this has nothing to do with anonymous methods, it might give you some idea of how to pass a variable number of arguments
source to share
An action is a shorthand way to create a delegate that returns void and takes no arguments. If you want actions with an argument, you need to use the general form:
Action<int>
is a delegate that takes one int parameter
Action<string, double>
takes 2 parameters: first the second string is double.
source to share