前面一篇裡提到事件是通過委托來進行關聯的,而委托是可以帶各種各樣的參數的,其中就可以用事件參數(EventArgs),同時,也可以用.Net框架裡邊提供的一個委托EventHandler來Handle事件。
一樣,搞一個場景(這個場景是書裡的):買車。經銷商(CarDealer)會上新車(NewCar)事件,這個事件會由買車的顧客(Comsumer)訂閱,一旦有新車出來他們就會來光顧。在這裡,由於需要詳細的車的信息,所以使用前面提到的不帶參數的方法就比較麻煩,我們重新定義一個委托(delegate)和事件參數(EventArgs)。
1、事件參數(CarInfoEventArgs)
從.Net提供的EventArgs裡派生出來,包含車輛名字的屬性
public class CarInfoEventArgs : EventArgs { public string Car { get; private set; } public CarInfoEventArgs(string car) { this.Car = car; } }
2、事件(NewCarInfo)
這裡使用.Net自帶的委托EventHandler來聲明一個事件,相應的,這個事件的處理程序就必須使用這個委托對應的參數來構建
public event EventHandler<CarInfoEventArgs> NewCarInfo;
注意,這是一個泛型委托,在這裡指定了參數的類型為CarInfoEventArgs,EventHandler的定義如下:
public delegate void EventHandler<TEventArgs>(object sender, TEventArgs e) where TEventArgs : EventArgs
可以看到這個委托包含兩個參數:一個object類型,一個泛型參數,並且這個泛型參數被限制為EventArgs或EventArgs派生的類型
3、完整的對象
CarDealer
public class CarDealer { public event EventHandler<CarInfoEventArgs> NewCarInfo; // 觸發事件 public void NewCar(string car) { Console.WriteLine($"CarDealer, new car {car}"); if (NewCarInfo != null) { NewCarInfo(this, new CarInfoEventArgs(car)); } } }
Consumer
public class Consumer { public string Name { get; private set; } public Consumer(string name) { this.Name = name; } public void NewCarIsHere(object sender, CarInfoEventArgs e) { Console.WriteLine($"{name}: car {e.Car} is new"); } }
4、具體的實現
public class Program { static void Main() { var dealer = new CarDealer(); var michael = new Consumer("Michael"); dealer.NewCarInfo += michael.NewCarIsHere; dealer.NewCar("Mercedes"); var nick = new Consumer("Nick"); dealer.NewCarInfo += nick.NewCarIsHere; dealer.NewCar("Ferrari"); dealer.NewCarInfo -= michael.NewCarIsHere; dealer.NewCar("Toyota"); } }
執行結果如下: