在委托c#中“清除”所有链式方法

时间:2012-11-23 13:24:32

标签: c# .net delegates

我有一种情况需要使用匿名方法语法(D += delegate(...){})将方法链接到委托D.但是,我需要确保在添加新方法之前删除其他链式方法。

我知道我可以做D - = a,D + = b之类的事情,但由于我使用的是匿名方法,我不确定-=是否有用(因为我没有有一个明确的名字。)。

如果我的推理是正确的,有没有办法可以使用匿名语法删除所有链式方法?

提前致谢。

2 个答案:

答案 0 :(得分:2)

我不得不收回原来的答案,因为它错了,评论(在问题和我的答案下)提供了一些额外的信息。

对于事件和委托,您可以简单地使用=指定null(或新的侦听器)以除去所有其他侦听器 - 但只能在与定义事件/委托相同的类中。

我发现通过常规方法不可能从未在同一个类中声明的事件中删除所有侦听器,但是您可以通过查找事件/委托并使用{为其分配null来使用Reflection来执行此操作。 {1}}。

这是一个旧的SO问题的链接,可能与您的问题有类似的限制。这个特别的答案对我有用: https://stackoverflow.com/a/8108103/1659828

答案 1 :(得分:0)

委托类型是不可变类型。如果D是委托类型的实例,则它包含一个固定长度的调用列表,其中包含一个或更多项。

所以你不能“清除”清单。您也无法使用空调用列表创建新实例,因为null引用(不是实例)用于没有方法的情况。

示例(MyMethodJonnysMethod是方法组,而不是委托变量):

Action D = null;   // no object, no invocation list

D += MyMethod;     // null and new Action(MyMethod) are combined; result is assigned to D
// D is an instance, invocation list length is 1
D += JonnysMethod; // two instances are combined; D is assigned to new instance; original instances are no longer referenced and will "soon" be garbage collected
// D is an instance, invocation list length is 2

D -= MyMethod;     // D is assigned to a new instance again
D -= JonnysMethod; // D is assigned to null; no new instance

注意:如果D确实是一个事件,请小心。如果您在定义D的类/结构之外,+=-=是对事件访问者的调用。因此,在这种情况下,它们不是直接的代理组合。如果您位于定义D的类/结构中,并且D是“类似字段”的事件,D可以在两种意义上使用。作为委托变量(事件的“隐藏”支持字段),以及作为事件。 +=-=的含义可以用两种方式解释。在C#3之前,它直接在后备字段被解释为委托组合。在C#4和C#5中,语义被更改,+=-=是在这种情况下对事件访问者的调用。