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

C#事件实现(文章与反射器),c#,events,C#,Events,公共类事件类型 { 公共事件EventHandler>NewEvent public void SmthHappened(string data) { MyEventArgs<Object> eventArgs = new MyEventArgs<Object>(data); OnNewEvent(eventArgs); } private void OnNewEvent(MyEventArgs<Ob

公共类事件类型 { 公共事件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);
        }
    }
}
public void SMTHOccessed(字符串数据)
{
MyEventTargs eventArgs=新的MyEventTargs(数据);
OnNewEvent(事件参数);
}
私有void OnNewEvent(MyEventArgs eventArgs)
{
EventHandler tempEvent=NewEvent;
if(tempEvent!=null)
{                
tempEvent(此为eventArgs);
}
}
}
我希望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);
    }
}
private EventHandler\u newEvent;
公共事件处理程序NewEvent
{
[MethodImpl(MethodImplOptions.Synchronized)]
添加
{
_newEvent=(EventHandler)Delegate.Combine(_newEvent,value);
}
[MethodImpl(MethodImplOptions.Synchronized)]
去除
{
_newEvent=(EventHandler)委托。删除(_newEvent,value);
}
}
,但反射器表示其实现方式如下:

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);
    }
}
公共事件事件处理程序NewEvent
{
添加
{
事件处理程序句柄2;
EventHandler newEvent=this.newEvent;
做
{
handler2=新事件;
eventhandler3=(EventHandler)Delegate.Combine(handler2,value);
newEvent=联锁的.CompareExchange(参考this.newEvent,handler3,handler2);
}
while(newEvent!=handler2);
}
去除
{
事件处理程序句柄2;
EventHandler newEvent=this.newEvent;
做
{
handler2=新事件;
EventHandler handler3=(EventHandler)委托。删除(handler2,值);
newEvent=联锁的.CompareExchange(参考this.newEvent,handler3,handler2);
}
while(newEvent!=handler2);
}
}

请smb解释一下为什么会这样

这个问题的答案在很大程度上取决于您使用的版本。这些年来,它被改进了很多。基本上是这样的。它使其线程安全,无需锁定。这并不是唯一的改变——它还改变了类中类似字段事件的引用的解析方式:+=和-=现在通过“添加”和“删除”位,而不是直接使用支持字段


请注意,此更改会影响使用C#4编译器编译的代码,即使是针对较旧的框架;锁定也有一些更改,这些更改只影响针对.NET 4编译的代码,因为它使用了一个新方法()。

您所期望的是一个简单的非线程安全实现。类似字段的事件语法始终提供线程安全语法(因此是reflector版本)。请参阅本文以了解事件及其实现方式。

我刚刚查看了使用Roslyn(so C#6)编译的事件的反编译源,我仍然看到使用CompareExchange的do…while循环。哪个版本使用了Monitor.TryEnter()?你还记得吗?