Delegáty v .NETu umožňují, aby se metoda (odkaz na metodu) mohla předávat jako parametr jiné metody.
K čemu potřebujeme předávat metody jako parametry? Kvůli jevu zvanému "call-back", tedy jakési "zavolej mi zpátky". Až nastane určitá situace (dojde k nějaké události), potřebuji, aby ten, komu předávám odkaz na mou metodu jako parametr, tuto metodu zavolal.
Příklad:
Pověřím svého brokera na burze, aby sledoval vývoj cen a až cena akcií u mnou vytipované firmy
klesne pod např. pod 10 dolarů za akcii, broker mi má zavolat. Já ho pak třeba pověřím tím,
aby nakoupil 50procentní podíl v té firmě.
Příklad syntaxe pro definování delegáta:
// Decide whether to buy shares. // Parameters: // pricePerShare .... Price of one share (in USD). // prospect ......... Prospect of exchange rate movements: >0 means the price should go up, =0 the price should be more or less the same, <0 the price should drop. // Returns: // true ............. Do buy shares up to 50% in the company. // false ............ Do NOT buy, wait. public delegate bool DecideBuy(decimal pricePerShare, int prospect);
Příklad syntaxe pro použití delegáta:
public static void Main(string[] args) { DecideBuy decideBuyMethod = new DecideBuy(AssessSituationAndDecide); } public static bool AssessSituationAndDecide(decimal priceOfOneShare, int futureEstimate) { if ( (priceOfOneShare < 10.0M) && (futureEstimate > 0) ) { return true; } return false; }
Tam, kde delegáta použijeme, je rozhodující pouze signatura, tj. počet a typy parametrů a typ návratové hodnoty. Nezáleží na názvu metody ani na tom, zda je metoda např. statická, nebo patří nějaké instanci.
Lambda funkce zastupují jednoduché metody, typicky s nějakými parametry a nějakou návratovou hodnotou. Proto funkce. Lambda se jim říká z historických důvodů, kdy se speciální anonymní funkce ve funkcionálním programování označovaly písmenem řecké abecedy lambda (λ). Viz např. jazyk LISP.
Lambda funkce se často využívají na místě delegátů, kdy to, co se má provést při tzv. "call-backu", je tak jednoduchá akce, že je zbytečné na ni psát novou metodu. Místo toho použijeme jednoduchý lambda výraz, který je navíc často i čitelnější než celá metoda.
Lambda výraz se píše v místě použití delegáta, kde bychom jinak psali pouze jméno naší metody a vlastní kód oné metody by musel ten, kdo si prohlíží náš program, hledat jinde.
Definice delegáta
public delegate bool DecideBuy(decimal pricePerShare, int prospect);
Použití delegáta – varianta s celou metodou
public class Broker { private DecideBuy methodToDecide; public void RegisterCallBack(DecideBuy decideBuy) { this.methodToDecide = decideBuy; } public void StartWatchingPrices() { while (true) { decimal price = GetCurrentPricePerShare(); int prospect = GetFutureProspect(); bool clientDecidedToBuy = this.methodToDecide(price, prospect); if (clientDecidedToBuy) { BuyStock(); break; } SleepAnHour(); } } }
public class Program { public static void Main(string[] args) { Broker broker = new Broker(); broker.RegisterCallBack(new DecideBuy(AssessSituationAndDecide)); broker.StartWatchingPrices(); } public static bool AssessSituationAndDecide(decimal priceOfOneShare, int futureEstimate) { if ( (priceOfOneShare < 10.0M) && (futureEstimate > 0) ) { return true; } return false; } }
Použití delegáta – varianta s lambda výrazem
public class Program { public static void Main(string[] args) { Broker broker = new Broker(); broker.RegisterCallBack( (price, prospect) => price < 10.0M && prospect > 0 ); broker.StartWatchingPrices(); } }