如何在C#中向动作添加另一个动作?
c#
为什么这段代码只会打印“A”和“B”,而不是“C”?
Action act = null;
act += () => MessageLog.Message("A");
act += () => MessageLog.Message("B");
Action<Action> add = a => a += () => MessageLog.Message("C");
add(act);
act.Invoke();
回答
代表是不可变的。在+=操作创建一个新的与由来自左侧的调用列表的调用列表的委托,随后从操作者的右手边调用列表。然后它将对该委托的引用存储在左侧的变量中。所以
act += () => MessageLog.Message("A");
相当于
act = act + (Action) (() => MessageLog.Message("A"));
这又相当于:
act = act + (Action) (() => MessageLog.Message("A"));
所以,现在我们可以来找你的add代表了。这个 lambda 表达式:
act = (Action) Delegate.Combine(act, (Action) (() => MessageLog.Message("A"));
...修改参数a以引用新组合的委托...然后忽略它。
相反,您需要返回组合委托(因此更改add为 a Func<Action, Action>),然后在调用时使用返回值add:
a => a += () => MessageLog.Message("C");