c# - .NET 事件引发和空对象模式

标签 c# .net events design-patterns

我们可以通过两种方式引发事件:

public event EventHandler MyEvent;

private void DoSomething()
{
    ...
    var handler = MyEvent;
    if (handler != null)
        handler(this,EventArgs.Empty);
}

public event EventHandler MyEvent = (o,e) => {} ;

private void DoSomething()
{
    ...
    MyEvent(this, EventArgs.Empty);
}

我更喜欢最后一个。它更短。
我的同事坚持第一种变体。

第一个比第二个有什么优势吗?

最佳答案

C# 6 更新

在 C# 6 中,您只需像这样使用 null 条件运算符:

PropertyChanged?.Invoke(this, args);

这是 recommended by the Roslyn wiki

原始答案

Eric Lippert 有 a great blog post on Events and Races ,如果您还没有阅读,您应该阅读。

第一个选项可以被认为比第二个选项更安全,因为事件可能会被设置为 null。有人可能会不小心修改类。此外,如果您反序列化实例,则第二种方法将不起作用(取决于您使用的序列化机制)。

我有时会使用辅助方法来引发事件

static class Raiser
{
    public static void Raise<T>(this EventHandler<T> evnt, object sender, T args)
        where T : EventArgs
    {
        if (evnt != null)
        {
            evnt(sender, args);
        }
    }
}

class SomeClass
{
    public event EventHandler<EventArgs> MyEvent;

    private void DoSomething()
    {
        MyEvent.Raise(this, EventArgs.Empty);
    }
}

关于c# - .NET 事件引发和空对象模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13629051/

相关文章:

.net - StringBuilder.AppendLine() 不会创建新行

c# - 冗余转换是否得到优化?

android - 在 Android 中,当我通过 Activity 中的代码设置值时,如何停止 TextChange 事件?

javascript - 为什么这个 jQuery 事件会运行两次?

c# - WebAPI XML 格式化程序不返回所有字段

c# - Firebase .NET token 验证

c# - C# 对象在不可访问时是否从内存中删除

java - 如何将事件处理程序添加到 Minecraft Forge 中的 block 控制杆?

c# - 从非托管进程卸载 .NET DLL

c# - 获取或设置访问器预期的枚举