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 that the line
action -= printAction;
Actually translates into
action = (Action) Delegate.Remove(action, printAction);
so the action captured by _captureAction in CaptureActionFromParam() is not changed - only the local 'action' variable in TestSimpleCapturedAction() is affected.
My desired behavior in such a scenario would be printAction not being called. The only solution I can think of is defning a new "delegate container" class as such:
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 my desired behavior can be achieved without introducing this new layer of abstraction. Implementing the strategy pattern can easily lead to such a situation, so one would reckon the language and/or the BCL would support it natively somehow.
Thanks !