前面[C#]RaiseEvent Extension Method (一)這篇介紹了如何用擴充方法來簡化C#事件的觸發動作,最近在做觸發事件時,又看到了一個引起我關注的重點,那就是有時候我們在初始化事件的參數時費了很大的耗費,準備觸發事件時,透過OnXXX去觸發事件,結果發現事件並未被繫上,整個事件觸發的動作就不做了,那麼前面所作的參數準備不就是不必要的耗費? … Var e = new MyEventArgs() {…}; … OnMyEvent(e); …

當然這樣的問題可以在觸發事件的地方用if判別去避開,但這樣就會讓程式在維護與閱讀上的困難度上升,筆者在[.Net Concept]理解事件的宣告方式與用法這篇有對此做詳細的描述,這邊不多做解釋。

因為有上面的原因,筆者又花了一點時間將擴充方法做了些改進,增加兩個多載版本,使其能帶入初始化事件參數的方法,如此在事件未繫上時就不會做初始的動作。

public static class ObjectExtension { public static void RaiseEvent(this object obj, EventHandler handler, EventArgs e) { RaiseEvent(obj, handler, () => e); }

public static void RaiseEvent(this object obj, EventHandler handler, Func func) { if (handler == null) return; handler(obj, func()); }

public static void RaiseEvent(this object obj, EventHandler handler, TEventArgs e) where TEventArgs : EventArgs { RaiseEvent(obj, handler, () => e); }

public static void RaiseEvent(this object obj, EventHandler handler,Func func) where TEventArgs : EventArgs { if (handler == null) return; handler(obj, func()); } }

使用上透過Lambda的輔助也十分的好上手。

this.RaiseEvent(MyEvent, () => new MyEventArgs() { //Init EventArgs … });

完整的範例程式如下:

using System; using System.Collections.Generic; using System.Linq; using System.Text;

namespace ConsoleApplication14 { class Program { static void Main(string[] args) { Person Larry = new Person(); Larry.NameChanged += new EventHandler(Larry_NameChanged); Larry.; } static void Larry_NameChanged(object sender, NameEventArgs e) { Console.WriteLine(string.Format(“NameChanged to {0}”, e.Name)); } } public static class ObjectExtension { public static void RaiseEvent(this object obj, EventHandler handler, EventArgs e) { RaiseEvent(obj, handler, () => e); }

public static void RaiseEvent(this object obj, EventHandler handler, Func func) { if (handler == null) return; handler(obj, func()); }

public static void RaiseEvent(this object obj, EventHandler handler, TEventArgs e) where TEventArgs : EventArgs { RaiseEvent(obj, handler, () => e); }

public static void RaiseEvent(this object obj, EventHandler handler,Func func) where TEventArgs : EventArgs { if (handler == null) return; handler(obj, func()); } }

class NameEventArgs : EventArgs { public string Name { get; set; } }

class Person { private string name; public string Name { get { if ( null) return string.Empty; return _name; } set { if (_name != value) { _ this.RaiseEvent(NameChanged, () => new NameEventArgs() { }); } } } public event EventHandler NameChanged; }

}

運行的結果如下: