以匿名方法捕获代表

Oha*_*der 4 c# delegates strategy-pattern

考虑

    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();
    }
Run Code Online (Sandbox Code Playgroud)

printAction将由_captureAction调用的原因是该行

action -= printAction;
Run Code Online (Sandbox Code Playgroud)

实际上翻译成

action = (Action) Delegate.Remove(action, printAction);
Run Code Online (Sandbox Code Playgroud)

因此,CaptureActionFromParam()中_captureAction捕获的操作不会更改 - 只会影响TestSimpleCapturedAction()中的本地"action"变量.

在这种情况下我想要的行为是printAction没有被调用.我能想到的唯一解决方案是定义一个新的"委托容器"类:

    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();
    }
Run Code Online (Sandbox Code Playgroud)

这有效,但我想知道如果不引入这个新的抽象层,我是否可以实现我想要的行为.实施策略模式很容易导致这种情况,因此人们会认为语言和/或BCL会以某种方式本地支持它.

谢谢 !

Eri*_*ert 7

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

如果要捕获的是一个可以变化的委托,则捕获包含对委托的引用的变量.变量各不相同,这就是为什么它们被称为"变量".如果你想要一些可以变化的东西,那就得到变量吧.

    CaptureActionFromParam(()=>{action();}); 
Run Code Online (Sandbox Code Playgroud)

现在,捕获的委托本身捕获了变量 "action",而不是恰好在其中的.

记得:

  • 参数按值传递.
  • Lambdas捕获变量,而不是.

合理?