C#中為什麼用事件代替委託?
阿新 • • 發佈:2022-03-20
為什麼我們要在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 = newWhyUseEvents(); 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、當然了,第三點就是阻止呼叫委託。