Delegát (CLI) - Delegate (CLI)
A delegát je forma typově bezpečné ukazatel funkce používá Společná jazyková infrastruktura (CLI). Delegáti specifikují a metoda volat a volitelně objekt zavolat metodu. Delegáti se používají mimo jiné k provádění zpětná volání a posluchači událostí. Objekt delegáta zapouzdřuje odkaz na metodu. Objekt delegáta lze poté předat kódu, který může volat odkazováno metoda, aniž byste museli v době kompilace vědět, která metoda bude vyvolána.
A delegát vícesměrového vysílání je delegát, který poukazuje na několik metod.[1][2] Multicast delegování je mechanismus, který poskytuje funkce pro provádění více než jedné metody. Existuje seznam delegátů udržovaných interně a při vyvolání multicastového delegáta se provede seznam delegátů.
V C # se delegáti často používají k implementaci zpětných volání v programování řízeném událostmi. Například delegát může být použit k označení, která metoda by měla být volána, když uživatel klikne na nějaké tlačítko. Delegáti umožňují programátorovi upozornit několik metod, že došlo k události.[3]
Příklad kódu C #
Kód pro deklaraci a delegát typ, pojmenovaný SendMessageDelegate, který trvá a Zpráva jako parametr a vrátí se prázdnota:
delegát prázdnota SendMessageDelegate(Zpráva zpráva);
Kód k definování metody, která vezme instančního delegáta jako argument:
prázdnota Poslat zprávu(SendMessageDelegate sendMessageDelegateReference){ // Synchronně zavoláte delegáta a všechny ostatní zřetězené delegáty. sendMessageDelegateReference(Nový Zpráva(„ahoj toto je ukázková zpráva“));}
Implementovaná metoda, která se spustí, když se volá delegát:
prázdnota HandleSendMessage(Zpráva zpráva){ // Implementace pro třídy Sender a Message nejsou pro tento příklad relevantní. Odesílatel.Poslat(zpráva);}
Kód pro volání metody SendMessage, předání instančního delegáta jako argumentu:
Poslat zprávu(Nový SendMessageDelegate(HandleSendMessage));
Delegáti (C #)
delegát prázdnota Oznamovatel(tětiva odesílatel); // Normální podpis metody s delegátem klíčového slovaOznamovatel pozdravit; // Proměnná delegátaprázdnota Jak se máte(tětiva odesílatel) { Řídicí panel.WriteLine("Jak se máte, " + odesílatel + '?');}pozdravit = Nový Oznamovatel(Jak se máte);
Proměnná delegáta volá přidruženou metodu a volá se následovně:
pozdravit(„Anton“); // Volá HowAreYou („Anton“) a tiskne „How are you, Anton?“
Delegované proměnné jsou prvotřídní objekty formuláře Nový DelegateType(obj.Metoda)
a lze jej přiřadit k jakékoli metodě shody nebo k hodnotě nula
. Ukládají metodu a jeho přijímač bez jakýchkoli parametrů:[4]
Nový DelegateType(funnyObj.Jak se máte);
Objekt funnyObj
může být tento
a vynechán. Pokud je metoda statický
, neměl by to být objekt (v jiných jazycích se také nazývá instance), ale samotná třída. To by nemělo být abstraktní
, ale mohl být Nový
, přepsat
nebo virtuální
.
Chcete-li úspěšně zavolat metodu s delegátem, musí se podpis metody shodovat s DelegateType
se stejným počtem parametrů stejného druhu (ref
, ven
, hodnota
) se stejným typem (včetně návratového typu).
Multicast delegáti (C #)
Proměnná delegáta může obsahovat více hodnot současně:
prázdnota Jak se máte(tětiva odesílatel) { Řídicí panel.WriteLine("Jak se máte, " + odesílatel + '?');}prázdnota Jak se dneska máš(tětiva odesílatel) { Řídicí panel.WriteLine("Jak se dneska máš, " + odesílatel + '?');}Oznamovatel pozdravit;pozdravit = Jak se máte;pozdravit += Jak se dneska máš;pozdravit("Leonardo"); // „Jak se máš, Leonardo?“ // „Jak se dnes máš, Leonardo?“pozdravit -= Jak se máte;pozdravit("Pereira"); // „Jak se dnes máš, Pereire?“
Pokud je delegát vícesměrového vysílání funkcí nebo nemá číslo ven
parametr, vrátí se parametr posledního volání.[5]
Technické podrobnosti implementace
I když interní implementace se může lišit, delegovat instance lze považovat za n-tice z objekt a a metoda ukazatel a a odkaz (případně null) jinému delegátovi. Z tohoto důvodu je odkaz na jednoho delegáta možná odkazem na více delegátů. Když první delegát dokončí, pokud jeho odkaz na řetěz není null, bude vyvolán další a tak dále, dokud nebude seznam úplný. Tento vzor umožňuje událost mít snadné škálování režie od jediného odkazu až po odeslání do seznamu delegátů a je široce používán v CLI.
Výkon
Výkon delegátů býval mnohem pomalejší než a virtuální nebo rozhraní volání metody (v testech společnosti Microsoft z roku 2003 6 až 8krát pomalejší),[6] ale protože .SÍŤ 2.0 CLR v roce 2005 je to přibližně stejné jako volání rozhraní.[7] To znamená, že ve srovnání s přímými vyvoláními metod existuje malá přidaná režie.
Na konstrukci tříd delegátů existují velmi přísná pravidla. Tato pravidla umožňují optimalizaci překladačů velkou volnost při optimalizaci delegátů při zajištění bezpečnosti typu.[Citace je zapotřebí ]
Viz také
Reference
- ^ Článek Microsoft Developer Network (MSDN), Jak: Kombinovat delegáty (delegáti vícesměrového vysílání) (C # Programming Guide), Přístup 5/20/2008
- ^ Delegáti „O společnosti Microsoft“"". Sun Developer Network. Sun Microsystems. Archivovány od originál dne 10. února 1999.
- ^ Wikibooks: C Sharp Programming / Delegates and Events
- ^ Mössenböck, Hanspeter (2002-03-25). „Advanced C #: Variabilní počet parametrů“ (PDF). http://ssw.jku.at/Teaching/Lectures/CSharp/Tutorial/: Institut für Systemsoftware, Johannes Kepler Universität Linz, Fachbereich Informatik. str. 23–24. Citováno 2011-08-04.
- ^ Mössenböck, Hanspeter (2002-03-25). „Advanced C #: Variabilní počet parametrů“. Institut für Systemsoftware, Johannes Kepler Universität Linz, Fachbereich Informatik. str. 25. Citováno 2011-08-04.
- ^ Gray, Jan (červen 2003). „Psaní rychlejšího spravovaného kódu: Zjistěte, co stojí“. Microsoft. Citováno 2007-09-09.
- ^ Sturm, Oliver (01.09.2005). „Volání delegáta se v .NET 2 výrazně zrychlilo“. Citováno 2007-09-09.