我正在使用C#、. NET 3.5。我了解如何利用事件,如何在类中声明事件,如何将它们与其他地方挂钩等等。一个人为的示例:
public class MyList { private List<string> m_Strings = new List<string>(); public EventHandler<EventArgs> ElementAddedEvent; public void Add(string value) { m_Strings.Add(value); if (ElementAddedEvent != null) ElementAddedEvent(value, EventArgs.Empty); } } [TestClass] public class TestMyList { private bool m_Fired = false; [TestMethod] public void TestEvents() { MyList tmp = new MyList(); tmp.ElementAddedEvent += new EventHandler<EventArgs>(Fired); tmp.Add("test"); Assert.IsTrue(m_Fired); } private void Fired(object sender, EventArgs args) { m_Fired = true; } }
但是,我 不 明白的是,当有人声明一个事件处理程序时
public EventHandler<EventArgs> ElementAddedEvent;
它从未被初始化-那么,ElementAddedEvent到底是什么?它指向什么?以下内容将不起作用,因为EventHandler从未初始化:
[TestClass] public class TestMyList { private bool m_Fired = false; [TestMethod] public void TestEvents() { EventHandler<EventArgs> somethingHappend; somethingHappend += new EventHandler<EventArgs>(Fired); somethingHappend(this, EventArgs.Empty); Assert.IsTrue(m_Fired); } private void Fired(object sender, EventArgs args) { m_Fired = true; } }
我注意到有一个EventHandler.CreateDelegate(…),但是所有方法签名都表明这仅用于通过典型的ElementAddedEvent + = new EventHandler(MyMethod)将Delegates附加到已经存在的EventHandler。
我不知道 是什么 ,我试图做将帮助......但最终我想拿出在LINQ一个抽象父的DataContext他们的孩子可以注册自己想要的表类型“观察”这样我就可以有事件例如BeforeUpdate和AfterUpdate,但特定于类型。像这样:
public class BaseDataContext : DataContext { private static Dictionary<Type, Dictionary<ChangeAction, EventHandler>> m_ObservedTypes = new Dictionary<Type, Dictionary<ChangeAction, EventHandler>>(); public static void Observe(Type type) { if (m_ObservedTypes.ContainsKey(type) == false) { m_ObservedTypes.Add(type, new Dictionary<ChangeAction, EventHandler>()); EventHandler eventHandler = EventHandler.CreateDelegate(typeof(EventHandler), null, null) as EventHandler; m_ObservedTypes[type].Add(ChangeAction.Insert, eventHandler); eventHandler = EventHandler.CreateDelegate(typeof(EventHandler), null, null) as EventHandler; m_ObservedTypes[type].Add(ChangeAction.Update, eventHandler); eventHandler = EventHandler.CreateDelegate(typeof(EventHandler), null, null) as EventHandler; m_ObservedTypes[type].Add(ChangeAction.Delete, eventHandler); } } public static Dictionary<Type, Dictionary<ChangeAction, EventHandler>> Events { get { return m_ObservedTypes; } } } public class MyClass { public MyClass() { BaseDataContext.Events[typeof(User)][ChangeAction.Update] += new EventHandler(OnUserUpdate); } public void OnUserUpdated(object sender, EventArgs args) { // do something } }
考虑到这一点,使我意识到我不太了解事件发生后的状况-我想理解:)
我已经在文章中详细介绍了这一点,但是这里是总结,假设您对委托人自己很满意:
对于类似字段的事件,需要进行一些同步,否则添加/删除仅调用Delegate。合并 / 删除以更改自动生成的字段的值。这两个操作都分配给后备字段-请记住,委托是不可变的。换句话说,自动生成的代码非常像这样:
// Backing field
// The underscores just make it simpler to see what’s going on here. // In the rest of your source code for this class, if you refer to // ElementAddedEvent, you’re really referring to this field. private EventHandler __ElementAddedEvent;
// Actual event public EventHandler ElementAddedEvent { add { lock(this) { // Equivalent to __ElementAddedEvent += value; __ElementAddedEvent = Delegate.Combine(__ElementAddedEvent, value); } } remove { lock(this) { // Equivalent to __ElementAddedEvent -= value; __ElementAddedEvent = Delegate.Remove(__ElementAddedEvent, value); } } }
在您的情况下,所生成字段的初始值为null-,并且null如果所有订阅者都被删除,它将始终再次变为初始值,这就是Delegate.Remove的行为。
null
如果您希望“无操作”处理程序订阅您的事件,以避免无效检查,则可以执行以下操作:
public EventHandler<EventArgs> ElementAddedEvent = delegate {};
的delegate {}只是它不关心它的参数,所以没有任何一个匿名方法。
delegate {}
如果还有什么不清楚的地方,请询问,我将尽力帮助!