Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Vývojáři noví na platformě .NET často tápou při rozhodování mezi návrhem založeným na delegates a návrhem založeným na events. Volba delegátů nebo událostí je často obtížná, protože tyto dvě jazykové funkce jsou podobné. Události jsou dokonce sestaveny pomocí jazykové podpory pro delegáty. Deklarace obslužné rutiny události deklaruje typ delegáta.
Oba nabízejí scénář pozdní vazby: umožňují scénáře, kdy komponenta komunikuje voláním metody, která je známa pouze za běhu. Podporují metody jak pro jednoho, tak pro několik odběratelů. Tyto termíny se mohou označovat jako podpora unicastu a multicastu. Obě podporují podobnou syntaxi pro přidávání a odebírání obslužných rutin. Nakonec vyvolání události a volání delegáta použije přesně stejnou syntaxi volání metody. Obě podporují stejnou syntaxi metody Invoke() pro použití s operátorem ?..
Se všemi těmito podobnostmi je snadné mít potíže určit, kdy použít kterou možnost.
Naslouchání událostem je volitelné.
Nejdůležitějším aspektem při určování, kterou jazykovou funkci použít, je to, jestli musí být připojený odběratel nebo ne. Pokud váš kód musí volat kód zadaný odběratelem, měli byste použít návrh založený na delegátech, když potřebujete implementovat zpětné volání. Pokud váš kód dokáže dokončit veškerou svou práci bez volání předplatitelů, měli byste použít návrh založený na událostech.
Podívejte se na příklady vytvořené v této části. Kód, který jste vytvořili pomocí List.Sort(), musí mít funkci porovnávače, aby bylo možné prvky správně seřadit. Dotazy LINQ musí být dodány s delegáty, aby bylo možné určit, které prvky se mají vrátit. Oba používali návrh vytvořený s delegáty.
Zvažte událost Progress. Zaznamenává průběh úkolu. Úkol pokračuje bez ohledu na to, jestli jsou nějací posluchači.
FileSearcher je dalším příkladem. Nadále by vyhledával a našel všechny soubory, které byly hledané, a to i bez připojených odběratelů událostí. Ovládací prvky uživatelského rozhraní stále fungují správně, i když žádní posluchači nenaslouchají událostem. Oba používají návrhy založené na událostech.
Návratové hodnoty vyžadují delegáty.
Dalším aspektem je prototyp metody, který byste chtěli pro metodu delegáta. Jak jste viděli, delegáti, kteří se používají pro události, mají návratový typ void. Existují idiomy k vytvoření obslužných rutin událostí, které předávají informace zpět do zdrojů událostí prostřednictvím úprav vlastností objektu argumentu události. I když tyto idiomy fungují, nejsou tak přirozené jako vrácení hodnoty z metody.
Všimněte si, že tyto dvě heuristiky mohou být často přítomny: Pokud vaše metoda delegáta vrátí hodnotu, ovlivňuje algoritmus nějakým způsobem.
Události mají privátní vyvolání
Třídy jiné než ta, ve které je událost obsažena, mohou pouze přidávat a odebírat posluchače událostí; událost může vyvolat pouze třída obsahující událost. Události jsou obvykle členy veřejné třídy. Ve srovnání se delegáti často předávají jako parametry a ukládají se jako členy privátní třídy, pokud se vůbec ukládají.
Posluchače událostí mají často delší životnost
Delší životnost posluchačů událostí je slabším odůvodněním. Můžete ale zjistit, že návrhy založené na událostech jsou přirozenější, když zdroj událostí vyvolává události po dlouhou dobu. Příklady návrhu založeného na událostech pro ovládací prvky uživatelského rozhraní můžete zobrazit v mnoha systémech. Jakmile se přihlásíte k odběru události, může zdroj událostí vyvolat události po celou dobu životnosti programu. (Pokud je už nepotřebujete, můžete se odhlásit z událostí.)
Oproti tomu v mnoha návrhářských vzorech založených na delegátech, kde se delegát používá jako argument metody, není delegát po návratu této metody již použit.
Pečlivě vyhodnotit
Výše uvedené aspekty nejsou tvrdá a rychlá pravidla. Místo toho představují pokyny, které vám můžou pomoct rozhodnout, která volba je pro vaše konkrétní použití nejvhodnější. Vzhledem k tomu, že jsou podobné, můžete dokonce prototypovat obojí a zvážit, se kterým by bylo přirozenější pracovat. Oba zvládnou dobře scénáře s pozdní vazbou. Použijte ten, který nejlépe vystihuje váš návrh.