我应该在派生的事件args类(即EventArgs.Empty)中实现null对象模式吗?如果是这样 - 最好的方法是什么?

时间:2013-04-16 13:10:45

标签: c# .net design-patterns event-handling

System.EventArgs实现了一个null对象模式的变体 - 开发人员使用EventArgs.Empty而不是null来指定“没有什么有趣的”情况,大概是为了减轻消费者必须处理可能的空引用异常< / p>

我用派生的事件args类声明我自己的事件,比如ContosoEventArgs 我认为消费者能够传递像ContosoEventArgs.Empty这样的东西是很自然的(只有EventArgs.Empty不会起作用,因为这会尝试将基类的实例分配给变量他们习惯的派生类)。 但是,这很难实现 - Empty static属性不依赖于我可以在派生类中设置的一些受保护属性IsEmpty。如果是这样,我可以做类似的事情:

public class ContosoEventArgs : EventArgs
{
    public static ContosoEventArgs Empty
    {
        get
        {
            return new ContosoEventArgs{IsEmpty=true};
        }
    }
}

很干净!

但是,这样的属性不存在,据我所知,测试EventArgs实例为Empty-ness的唯一方法是与EventArgs.Empty进行比较。这意味着我现在需要实现operator == overload ... and operator!=,Equals(...)和GetHashCode()...所有的样板只是让我的专门事件args遵循来自的模式base EventArgs

我应该只允许空值吗? 我认为这几乎就是他们在框架中所做的 - MouseEventArgs和ImageClickEventArgs没有显示空对象模式实现的痕迹

或者我是否忽略了第三种选择?

1 个答案:

答案 0 :(得分:1)

我认为您可以使用此代码而不会重载平等成员:

public class ContosoEventArgs : EventArgs
{
    public new static readonly ContosoEventArgs Empty = new ContosoEventArgs();
}

如果查看EventArgs,它会使用静态实例进行比较:

 [ComVisible(true)]
[__DynamicallyInvokable]
[Serializable]
public class EventArgs
{
    [__DynamicallyInvokable]
    public static readonly EventArgs Empty = new EventArgs();

    static EventArgs()
    {
    }
    [__DynamicallyInvokable]
    [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
    public EventArgs()
    {
    }
}