Consider
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(); }
The reason printAction will be called by _captureAction is because the line
action -= printAction;
Actually translated into
action = (Action) Delegate.Remove(action, printAction);
therefore, the action taken by _captureAction in CaptureActionFromParam () does not change - only the local variable action in TestSimpleCapturedAction () is affected.
My desired behavior in such a scenario would not be to call printAction. The only solution I can think of is to define a new delegate container class:
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(); }
This works, but I wonder if the desired behavior can be achieved without introducing this new layer of abstraction. The introduction of a strategy template can easily lead to this situation, so the language could be considered and / or BCL would somehow support it.
Thanks!
source share