我有这个方法:
public override void respond(params string[] resargs)
{
foreach (command cmd in pndgcmds)
{
cmd(this);
}
if (objs[resargs[0]].status)
objs[resargs[0]].request(resargs);
else
{
pndgcmds.Add(
(myclass master) =>
{
if (master.objs[resargs[0]].status != true) return;
master.objs[resargs[0]].request(resargs);
//code to remove the delegate
});
}
}
检查对象是否能够响应,使其响应(如果有),否则将命令存储在字典中,以便在下次调用响应时检查并调用状态。
我有两个问题。
如何编写代码来删除委托?我不知道该怎么做。
正如您所看到的,委托的大部分内部工作依赖于方法参数。代表将如何表现?
提前致谢!
答案 0 :(得分:6)
匿名方法很难删除,因为captire-context的实例仅在创建时才可用,因此是必需的。幸运的是,有一个诀窍:
SomeDelegateType handler = null;
handler = (myclass master) =>
{
if (master.objs[resargs[0]].status != true) return;
master.objs[resargs[0]].request(resargs);
pndgcmds.Remove(handler);
};
pndgcmds.Add(handler);
现在这是一个自我取消订阅的处理程序,在调用时会取消订阅。请注意,要执行此操作,我们需要存储委托实例(handler
),但我们会在该变量上创建一个闭包。最初的=null
是明确分配的要求。
您应该注意到resargs
变量也被捕获,如果索引为零的值在订阅之后但在调用之前发生变化,这可能会导致混淆。如果你想使用值“now”,那么请关闭它:
SomeDelegateType handler = null;
string val = resargs[0];
handler = (myclass master) =>
{
if (master.objs[val].status != true) return;
master.objs[val].request(resargs);
pndgcmds.Remove(handler);
};
pndgcmds.Add(handler);