我希望能够对具有可变数量参数的匿名方法进行内联调用(有时不带参数,有时使用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
所以我不能让委托接受这样的论点。我的语法错了,还是不可能?或者我是否必须更改我应该用于字典的匿名方法的类型?
答案 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)
你做不到。 Action
和Action<T>
是不同的,不兼容的委托类型。
有几种方法可以弥补这一点。
一种方法是ActionDic
为Dictionary<string, Action<int>>
,但这可能无法满足您想要使用的所有可能的代表。
另一种方法是使ActionDic
类似于Dictionary<string, Delegate>
,但这样做会很麻烦,因为你需要准确知道传递每个函数的参数(及其类型)的确切数量。这些信息需要存储在某个地方的另一个数据结构中。
还有第三种方法是使ActionDic
成为Dictionary<string, Action<object[]>>
并要求委托从输入中解包所需的任何参数。调用者将负责确切知道要使用的参数。这将允许第二个选项的语法稍微不那么笨拙,但每个委托中需要更多代码。
答案 2 :(得分:2)
您正在谈论两个不同的代表,即Action
和Action<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个参数:第一个是字符串第二个是双倍。