1. 程式人生 > 其它 >C#中為什麼用事件代替委託?

C#中為什麼用事件代替委託?

為什麼我們要在C#中用事件代替委託?能不能只使用委託?為什麼要使用事件?今天這篇文章就分析一下為什麼使用事件的主要原因。

將程式碼分發給團隊開發端和團隊客戶端,開發端編寫了委託程式碼,客戶端將例項化並訂閱到委託。

團隊開發端

首先,我們只使用委託編寫如下程式碼:

 1 public delegate void YourLoggingHere();
 2  public class WhyUseEvents
 3  {
 4     public YourLoggingHere MyLogging;
 5     public void MyMainProgram()
 6     {
 7        ExecuteValidation();
8 } 9 10 private void ExecuteValidation() 11 { 12 //Execution of validation and logic here 13 //With some business rules etc. 14 15 if (MyLogging != null) 16 { 17 MyLogging.Invoke(); 18 } 19 } 20 }

如上所示,開發端聲明瞭“YourLoggingHere”委託,宣告委託變數“MyLogging”。現在,客戶端可以例項化這個類,使用委託變數並新增函式方法。

團隊客戶端

在下面的示例中,客戶端想要使用類並新增函式方法到“MyLogging”委託。他們可以新增很多想要新增的函式方法。在這個示例中,他們只添加了一個函式方法,如下:

1 WhyUseEvents why = new WhyUseEvents();
2   why.MyLogging += () =>
3   {
4     Console.WriteLine("Hi I am subscribing to the delegate.");
5   };

現在開發端和客戶端都能使用這些程式碼。但是,奇怪的是,客戶端能直接呼叫委託。

1 WhyUseEvents why = new
WhyUseEvents(); 2 why.MyLogging += () => 3 { 4 Console.WriteLine("Hi I am subscribing to the delegate."); 5 }; 6 7 why.MyLogging.Invoke(); //Team Client here can directly invoke the delegate!

如上面程式碼所示,在開發端不知情的情況 下,客戶端能直接呼叫委託。在呼叫委託前,首先要執行其它的驗證,因此,對於函式方法和變數的封裝性來說不是一種好的方式。

程式碼審查

我們再審查一下程式碼,在呼叫委託“MyLogging”前,首先在最終地呼叫委託前有驗證業務邏輯。

 1  private void ExecuteValidation()
 2   {
 3        //Execution of validation and logic here
 4        //With some business rules etc.
 5 
 6        if (MyLogging != null)
 7        {
 8            MyLogging.Invoke();
 9        }
10   }

怎麼解決?對,事件

開發端通過新增event關鍵詞就可以解決問題:

1 //public YourLoggingHere MyLogging;
2 public event YourLoggingHere MyLogging;

這樣,客戶就不能直接呼叫委託了。如果直接呼叫,就如下面所示那樣觸發錯誤資訊:

1 why.MyLogging.Invoke();
2 
3 //The event 'WhyUseEvents.MyLogging' can only appear on the left hand side of += or -= (except when used from within the type 'WhyUseEvents')   

這就簡單地解釋了雖然我們可以一直使用委託卻選擇事件的原因:

1、可以提供封裝性,不會暴露業務邏輯;

2、防止客戶端清除掉所有註冊到委託上的函式方法(在事件中這樣做不到);

why.MyLogging = null;

3、當然了,第三點就是阻止呼叫委託。