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

public class EventsType {public event EventHandler> NewEvent;

public void SmthHappened(string data) { MyEventArgs eventArgs = new MyEventArgs(data); OnNewEvent(eventArgs); } private void OnNewEvent(MyEventArgs eventArgs) { EventHandler<MyEventArgs> tempEvent = NewEvent; if (tempEvent != null) { tempEvent(this, eventArgs); } } } 

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

 private EventHandler<MyEventArgs> _newEvent; public event EventHandler<MyEventArgs> NewEvent { [MethodImpl(MethodImplOptions.Synchronized)] add { _newEvent = (EventHandler<MyEventArgs>)Delegate.Combine(_newEvent, value); } [MethodImpl(MethodImplOptions.Synchronized)] remove { _newEvent = (EventHandler<MyEventArgs>)Delegate.Remove(_newEvent, value); } } 

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

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

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

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

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

这个问题的答案很大程度上取决于您使用的版本。 多年来它经过了很多改进。 见http://blogs.msdn.com/b/cburrows/archive/2010/03/05/events-get-a-little-overhaul-in-c-4-part-i-locks.aspx

您期望的是一个简单的非线程安全实现。 像事件语法这样的字段总是提供线程安全语法(因此reflection器版本)。 请参阅此artcile以了解事件及其实施方式。