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会以某种方式本地支持它.
谢谢 !
代表就像字符串.它们被实现为引用类型,但它们的行为更像是不可变值类型.在字符串上添加或减去字符时,它不会更改字符串,它会生成一个新字符串作为新结果.当您从整数中添加或减去数字时,它不会更改整数,它会生成一个新结果,即新结果.当您从委托中添加或减少委托时,它不会更改委托; 它产生一个新的委托,这是结果.
如果要捕获的是一个可以变化的委托,则捕获包含对委托的引用的变量.变量各不相同,这就是为什么它们被称为"变量".如果你想要一些可以变化的东西,那就得到变量吧.
CaptureActionFromParam(()=>{action();});
Run Code Online (Sandbox Code Playgroud)
现在,捕获的委托本身捕获了变量 "action",而不是恰好在其中的值.
记得:
合理?
| 归档时间: |
|
| 查看次数: |
333 次 |
| 最近记录: |