Dela via


Särskilja ombud och händelser

Föregående

Utvecklare som är nya på .NET Core-plattformen kämpar ofta med att välja mellan en design baserad på delegates och en design baserad på events. Valet av ombud eller händelser är ofta svårt, eftersom de två språkfunktionerna är liknande. Händelser skapas även med hjälp av språkstöd för ombud.

Båda erbjuder ett scenario med sen bindning: de aktiverar scenarier där en komponent kommunicerar genom att anropa en metod som bara är känd vid körning. Båda stöder metoder för enstaka och flera prenumeranter. Du kan hitta detta som kallas singlecast- och multicast-stöd. Båda stöder liknande syntax för att lägga till och ta bort hanterare. När du skapar en händelse och anropar ett ombud används slutligen exakt samma metodanropssyntax. Båda stöder även samma Invoke() metodsyntax för användning med operatorn ?. .

Med alla dessa likheter är det lätt att ha svårt att avgöra när du ska använda vilken.

Det är valfritt att lyssna på händelser

Det viktigaste när du ska avgöra vilken språkfunktion som ska användas är om det måste finnas en ansluten prenumerant eller inte. Om koden måste anropa koden som tillhandahålls av prenumeranten bör du använda en design som baseras på ombud när du behöver implementera återanrop. Om koden kan slutföra allt sitt arbete utan att anropa prenumeranter bör du använda en design som baseras på händelser.

Tänk på exemplen som skapades under det här avsnittet. Koden som du skapade med hjälp av List.Sort() måste ges en jämförelsefunktion för att elementen ska kunna sorteras korrekt. LINQ-frågor måste levereras med ombud för att avgöra vilka element som ska returneras. Båda använde en design som skapats med ombud.

Överväg händelsen Progress . Den rapporterar förlopp för en aktivitet. Uppgiften fortsätter att fortsätta om det finns några lyssnare eller inte. Är FileSearcher ett annat exempel. Den skulle fortfarande söka och hitta alla filer som söktes, även utan några händelseprenumeranter kopplade. UX-kontroller fungerar fortfarande korrekt, även om det inte finns några prenumeranter som lyssnar på händelserna. Båda använder design baserat på händelser.

Returvärden kräver ombud

Ett annat övervägande är den metodprototyp som du vill använda för ombudsmetoden. Som du har sett har de ombud som används för händelser alla en ogiltig returtyp. Du har också sett att det finns idiom för att skapa händelsehanterare som skickar information tillbaka till händelsekällor genom att ändra egenskaperna för händelseargumentobjektet. Även om dessa idiom fungerar är de inte lika naturliga som att returnera ett värde från en metod.

Observera att dessa två heuristiker ofta båda finns: Om ombudsmetoden returnerar ett värde kommer det sannolikt att påverka algoritmen på något sätt.

Händelser har privat anrop

Andra klasser än den där en händelse finns kan bara lägga till och ta bort händelselyssnare. endast klassen som innehåller händelsen kan anropa händelsen. Händelser är vanligtvis medlemmar i offentliga klasser. Som jämförelse skickas ombud ofta som parametrar och lagras som medlemmar i den privata klassen, om de lagras alls.

Händelselyssnare har ofta längre livslängd

Att händelselyssnare har längre livslängd är en något svagare motivering. Du kan dock upptäcka att händelsebaserade design är mer naturliga när händelsekällan lyfter händelser under en lång tidsperiod. Du kan se exempel på händelsebaserad design för UX-kontroller på många system. När du prenumererar på en händelse kan händelsekällan generera händelser under programmets livslängd. (Du kan avbryta prenumerationen på händelser när du inte längre behöver dem.)

Jämför det med många ombudsbaserade design, där ett ombud används som argument till en metod, och ombudet används inte när metoden returneras.

Utvärdera noggrant

Ovanstående överväganden är inte hårda och snabba regler. I stället representerar de vägledning som kan hjälpa dig att avgöra vilket val som är bäst för din specifika användning. Eftersom de är liknande kan du till och med prototypa båda, och överväga vilket som skulle vara mer naturligt att arbeta med. Båda hanterar sena bindningsscenarier väl. Använd den som förmedlar din design på bästa sätt.