gpt4 book ai didi

c# - 在匿名方法中捕获委托(delegate)

转载 作者:太空狗 更新时间:2023-10-30 00:46:48 26 4
gpt4 key购买 nike

考虑

    Action _captureAction;
private void TestSimpleCapturedAction()
{
Action action = new Action(delegate { });
Action printAction = () => Console.WriteLine("Printing...");

action += printAction;
CaptureActionFromParam(action);
action -= printAction;

_captureAction(); //printAction will be called!
}

private void CaptureActionFromParam(Action action)
{
_captureAction = () => action();
}

printAction 将被 _captureAction 调用的原因是行

action -= printAction;

实际转化为

action = (Action) Delegate.Remove(action, printAction);

所以 CaptureActionFromParam() 中的 _captureAction 捕获的 Action 没有改变——只有 TestSimpleCapturedAction() 中的局部“ Action ”变量受到影响。

在这种情况下,我希望的行为是不调用 printAction。我能想到的唯一解决方案是定义一个新的“委托(delegate)容器”类:

    class ActionContainer
{
public Action Action = new Action(delegate { });
}

private void TestCapturedActionContainer()
{
var actionContainer = new ActionContainer();
Action printAction = () => Console.WriteLine("Printing...");

actionContainer.Action += printAction;
CaptureInvoker(actionContainer);
actionContainer.Action -= printAction;

_captureAction();
}

private void CaptureInvoker(ActionContainer actionContainer)
{
_captureAction = () => actionContainer.Action();
}

这行得通,但我想知道是否可以在不引入这个新的抽象层的情况下实现我想要的行为。实现策略模式很容易导致这种情况,因此人们会认为语言和/或 BCL 会以某种方式原生支持它。

谢谢!

最佳答案

委托(delegate)就像字符串。它们被实现为引用类型,但它们的行为更像不可变值类型。当您在字符串上添加或减去字符时,它不会更改字符串,它会生成一个新字符串,即新结果。当你从一个整数中添加或减去数字时,它不会改变整数,它会产生一个新的整数,即新的结果。当您从委托(delegate)中添加或减去委托(delegate)时,它不会更改任何一个委托(delegate);它产生一个新的委托(delegate),这就是结果。

如果您要捕获的是一个可以变化 的委托(delegate),则捕获一个包含对委托(delegate)的引用的变量。变量变化,这就是它们被称为“变量”的原因。如果您想要可以变化的东西,请获取变量。

    CaptureActionFromParam(()=>{action();}); 

现在被捕获的委托(delegate)本身捕获了变量“ Action ”,而不是恰好在其中的

记住:

  • 参数按值传递。
  • Lambda 捕获变量,而不是

有道理吗?

关于c# - 在匿名方法中捕获委托(delegate),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2303112/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com