區別委派和事件
決定以 delegates
為基礎的設計與以 events
為基礎的設計時,不熟悉 .NET Core 平台的開發人員通常十分糾結。 因為委派或事件這兩個的語言功能很類似,通常其選擇極為困難。 事件甚至是使用委派的語言支援所建置。
它們均會提供晚期繫結案例︰透過呼叫僅在執行階段已知的方法啟用元件通訊的案例。 兩者都支援單一和多個訂閱者方法。 您可能會發現這稱為單點傳送和多點傳送支援。 它們同時支援使用類似的語法來新增和移除處理常式。 最後,引發事件與呼叫委派會使用完全相同的方法呼叫語法。 兩者甚至都支援相同的 Invoke()
方法語法,以與 ?.
運算子搭配使用。
具有所有這些相似性時,會很難決定其使用時機。
接聽事件為選擇性
決定要使用之語言功能的最重要考量為是否都必須要有附加的訂閱者。 如果您的程式碼必須呼叫訂閱者所提供的程式碼,則當您需要實作回撥時,您應該使用以委派為基礎的設計。 如果您的程式碼可以完成其所有工作,而不需要呼叫任何訂閱者,則應該使用以事件為基礎的設計。
請考慮本節期間所建置的範例。 必須將電腦函式提供給您使用 List.Sort()
所建置的程式碼,才能適當地排序項目。 必須提供具有委派的 LINQ 查詢,才能判斷要傳回的項目。 兩者都是使用委派所建置的設計。
請考量 Progress
事件。 它會報告工作的進度。
不論是否有任何接聽程式,工作都會繼續進行。
FileSearcher
是另一個範例。 它仍然會搜尋並尋找所有看到的檔案,即使未附加任何事件訂閱者也是一樣。
UX 控制項仍然會正常運作,即使沒有任何訂閱者接聽事件也是一樣。 它們都會使用以事件為基礎的設計。
傳回值需要委派
另一個考量是您要用於委派方法的方法原型。 如您所見,用於事件的委派都會有 void 傳回型別。 您也已看到有慣用語可建立事件處理常式,以透過修改事件引數物件的屬性,將資訊傳回給事件來源。 雖然這些慣用語確實可以運作,但不像從方法傳回值一樣自然。
請注意,這兩種啟發學習法可能通常都存在︰如果委派方法傳回值,則在某個方面可能會影響演算法。
事件具有私人叫用
除了包含事件類別以外的類別,只能新增和移除事件接聽程式;僅包含該事件的類別可叫用事件。 通常事件是公開類別成員。 相較之下,如果委派完全儲存,其通常會以參數的形式傳遞並儲存為私人類別成員。
事件接聽程式通常會有較長的存留期
事件接聽程式具有較長的存留期是稍弱的理由。 不過,事件來源在一段長時間後引發事件時,您可能會發現事件設計更為自然。 您可以在許多系統上看到 UX 控制項以事件為基礎的設計的範例。 訂閱事件之後,事件來源可能會在整個程式存留期引發事件。 (不再需要事件時,即可取消與事件的訂閱)。
與許多委派設計相反,其中使用委派作為方法的引數,而且在該方法傳回之後不會使用委派。
仔細評估
上述考量不是很難和快速的規則。 相反地,它們所代表的指引可協助您決定最適合您特定使用方式的選項。 因為它們十分類似,所以您甚至可以建立原型,並考慮哪個使用起來更自然。 它們也都會處理晚期繫結案例。 請使用用來溝通最佳設計的案例。