如何使匿名方法接受可变数量的参数?

时间:2013-02-04 06:50:51

标签: c# syntax delegates arguments

我希望能够对具有可变数量参数的匿名方法进行内联调用(有时不带参数,有时使用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

所以我不能让委托接受这样的论点。我的语法错了,还是不可能?或者我是否必须更改我应该用于字典的匿名方法的类型?

4 个答案:

答案 0 :(得分:4)

如果要使用1个整数参数定义委托,可以使用Action<int>。例如:

Action<int> somethingArgs = (int n) => { n += 1; };

您尚未显示ActionDic变量是什么,但如果它是IDictionary<string, Action>,则无法使其生效,因为Action不接受参数。

另一方面,你可以做的是使用代表词典:

IDictionary<string, Delegate> ActionDic = ...
ActionDic["something"] = (Action)(() => { i += 1; }); 
ActionDic["somethingArgs"] = (Action<int>)((int n) => { n += 1; });

答案 1 :(得分:3)

你做不到。 ActionAction<T>是不同的,不兼容的委托类型。

有几种方法可以弥补这一点。

一种方法是ActionDicDictionary<string, Action<int>>,但这可能无法满足您想要使用的所有可能的代表。

另一种方法是使ActionDic类似于Dictionary<string, Delegate>,但这样做会很麻烦,因为你需要准确知道传递每个函数的参数(及其类型)的确切数量。这些信息需要存储在某个地方的另一个数据结构中。

还有第三种方法是使ActionDic成为Dictionary<string, Action<object[]>>并要求委托从输入中解包所需的任何参数。调用者将负责确切知道要使用的参数。这将允许第二个选项的语法稍微不那么笨拙,但每个委托中需要更多代码。

答案 2 :(得分:2)

您正在谈论两个不同的代表,即ActionAction<T>。您无法将Action<T>分配给Action

Action a1 = () => { i += 1; };
Action<int> a2 = (n) => { n += 1; };

我猜你有Dictionary<string,Action>,所以这个词典不能接受Action<T>的值。

作为旁注,我会说第二个委托是绝对无用的,因为它增加了int参数,按值传递,实际上什么都不做。

另请考虑阅读How To pass Optional Arguments。虽然它与匿名方法无关,但它可能会给你一些关于如何传递可变数量参数的线索

答案 3 :(得分:0)

Action是创建返回void并且不带参数的委托的简短方法。 如果您想要使用参数进行操作,则需要使用泛型形式:

Action<int>是一个带有一个int参数

的委托

Action<string, double>需要2个参数:第一个是字符串第二个是双倍。