在处理方法中删除委托成员时,可以使用equals赋值吗?

时间:2015-05-27 15:17:23

标签: c# delegates operators variable-assignment dispose

我的课程中有以下代码

public class Receiver : IReceiver
{

    public event EventHandler Received;

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (disposing)
        {
            if (Received != null)
            {
                foreach (EventHandler delegateMember in Received.GetInvocationList())
                {
                    Received -= delegateMember;
                }
            }
        }
    }
}

此代码的作用是,当我处理我的类时,任何连接到Received事件的事件都将被单独删除。

如果下面的简洁版本具有相同的效果,我一直想知道是否而不是如此冗长,

    protected virtual void Dispose(bool disposing)
    {
        if (disposing)
        {
            Received = null;
        }
    }

基本上,这归结为Microsoft在实现委托重载时如何创建运算符重载。我知道所有文档都说使用+ =来订阅,而= =取消订阅事件。我还看到该文档说当删除最后一个订阅者时,该事件将被指定为null。文档没有说的是将事件赋值为null,是否具有取消订阅所有事件的效果?

我很想知道这是否可行,如果有任何文档说明可能的简洁代码是正确的行为。

更新

我一直在使用c#编译器进行更多挖掘,并且发现null的赋值仅适用于定义事件的类。 + =和 - =始终可以从课程内外获得。这使我认为使用= null版本是可以接受的。然而,这是猜测,我仍然没有看到任何明确说明这是支持功能的文档。

1 个答案:

答案 0 :(得分:4)

没有理由不在这里将null分配给代表。

如果您不在定义事件的类之外,那么 只能分配null。对于使用该类的任何人,他们应该只关心他们自己的处理程序,他们可以添加或删除。他们无法访问其他人的处理程序。

您需要记住委托是不可变的。在事件上使用+=不会改变委托以向该委托添加新方法,它会创建一个新委托,在调用时,它会调用一起添加的两个委托。使用-=创建一个委托,该委托调用除第二个操作数之外的第一个操作数的所有调用。所以一遍又一遍地调用-=会不断创建越来越多的委托,每个委托调用的东西越来越少,直到最终你到达委托不再调用任何东西的程度。只分配null等同于创建一个不做任何事情的委托,并直接分配。

因此,当您在开始之前仍然存在分配给事件的原始委托时,一遍又一遍地调用-=,以及N个中间委托。也就是说,没有任何代表可能被任何有根元素引用,因此它们都有资格收集。如果您只是分配null,那么您仍然拥有原来相同的孤立委托,那么您就不再拥有任何这些中间委托了。