0

System.EventArgs 实现了空对象模式的一种变体——开发人员使用 EventArgs.Empty 而不是 null 来指定“这里没什么意思”的情况,大概是为了让消费者不必处理可能的空引用异常

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

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

又好又干净!

但是,这样的属性不存在,据我所知,测试 EventArgs 实例是否为空的唯一方法是与 EventArgs.Empty 进行比较。这意味着我现在需要实现运算符 == 重载...和运算符 !=、Equals(...) 和 GetHashCode()... 所有这些样板文件只是为了让我的专门事件参数遵循基本事件参数

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

还是我忽略了第三种选择?

4

1 回答 1

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()
    {
    }
}
于 2013-04-16T14:11:29.407 回答