C#事件实现(文章与反射器)

Gri*_*uev 4 c# events

public class EventsType {public event EventHandler> NewEvent;

    public void SmthHappened(string data)
    {
        MyEventArgs<Object> eventArgs = new MyEventArgs<Object>(data);
        OnNewEvent(eventArgs);
    }

    private void OnNewEvent(MyEventArgs<Object> eventArgs)
    {
        EventHandler<MyEventArgs<Object>> tempEvent = NewEvent;

        if (tempEvent != null)
        {                
            tempEvent(this, eventArgs);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我希望C#编译器会像这样翻译NewEvent:

private EventHandler<MyEventArgs<object>> _newEvent;

public event EventHandler<MyEventArgs<object>> NewEvent
{
    [MethodImpl(MethodImplOptions.Synchronized)]
    add
    {
    _newEvent = (EventHandler<MyEventArgs<object>>)Delegate.Combine(_newEvent, value);
    }
    [MethodImpl(MethodImplOptions.Synchronized)]
    remove
    {
    _newEvent = (EventHandler<MyEventArgs<object>>)Delegate.Remove(_newEvent, value);
    }
}
Run Code Online (Sandbox Code Playgroud)

,但Reflector表示它是以这种方式实现的:

public event EventHandler<MyEventArgs<object>> NewEvent
{
    add
    {
        EventHandler<MyEventArgs<object>> handler2;
        EventHandler<MyEventArgs<object>> newEvent = this.NewEvent;
        do
        {
            handler2 = newEvent;
            EventHandler<MyEventArgs<object>> handler3 = (EventHandler<MyEventArgs<object>>) Delegate.Combine(handler2, value);
            newEvent = Interlocked.CompareExchange<EventHandler<MyEventArgs<object>>>(ref this.NewEvent, handler3, handler2);
        }
        while (newEvent != handler2);
    }
    remove
    {
        EventHandler<MyEventArgs<object>> handler2;
        EventHandler<MyEventArgs<object>> newEvent = this.NewEvent;
        do
        {
            handler2 = newEvent;
            EventHandler<MyEventArgs<object>> handler3 = (EventHandler<MyEventArgs<object>>) Delegate.Remove(handler2, value);
            newEvent = Interlocked.CompareExchange<EventHandler<MyEventArgs<object>>>(ref this.NewEvent, handler3, handler2);
        }
        while (newEvent != handler2);
    }
}
Run Code Online (Sandbox Code Playgroud)

拜托,smb解释我为什么会这样?

Jon*_*eet 5

是的:基本上,C#4在这个领域做了一些改变.它使其无需锁定即可保证线程安全.这不是唯一的变化 - 它还会改变对类中类字段事件的引用的解决方式:+ =和 - =现在通过"添加"和"删除"位而不是直接使用支持字段.

请注意,此更改会影响使用C#4编译器编译的代码,甚至是旧框架; 还有一些锁定更改只会影响针对.NET 4编译的代码,因为它使用了一个新方法(Monitor.TryEnter(object, out bool)).