Undersøg sen binding med stedfortrædere
I C#bruges metoder til at udføre handlinger, f.eks. udføre en beregning eller hente oplysninger. Dine programmer bruger metoder til at opnå tilsigtede resultater og kalder metoderne, når bestemte betingelser er opfyldt. Programmer automatiserer ofte processer ved at få én metode til at kalde en anden, hvilket kan kalde tredje metode osv. Da betingelserne er kendt på kompileringstidspunktet, implementerer den eksekverbare kode foruddefinerede arbejdsprocesser på en forudsigelig måde. Du kan f.eks. have en metode, der genererer en månedlig kunderapport, når der klikkes på en knap. Når koden kører, og der klikkes på knappen, kaldes metoden , og rapporten genereres. Dette scenarie er et eksempel på tidlig binding, hvor den metode, der skal kaldes, bestemmes på kompileringstidspunktet. Tidlig binding er velegnet til mange scenarier, fordi det gør det nemt at læse og forstå koden. Du kan se programmets flow ved at følge metodekaldene. Koden er forudsigelig, og du ved præcis, hvilken metode der kaldes, når der klikkes på knappen.
Der er dog tidspunkter, hvor du ikke ved, hvilken metode du skal kalde, før programmet kører. Lad os f.eks. antage, at du arbejder på en app, der er afhængig af kørselsafhængigheder for at beslutte, hvilken metode der skal bruges til at analysere kundedata. Dette scenarie er et eksempel på sen binding, hvor den metode, der skal kaldes, bestemmes på kørselstidspunktet. I dette tilfælde kan den metode, der skal kaldes, afhænge af et eksternt ressourcebrugerinput eller programmets aktuelle tilstand.
I C#bruges stedfortrædere til at implementere sen binding.
Hvad er en stedfortræder?
En stedfortræder er en .NET-type, der er afledt af Delegate klassen og bruges til at indkapsle metoder. Ved at indkapsle metoder og instantiere dem som objekter giver stedfortrædere dig mulighed for at gemme metoder i variabler, overføre dem som argumenter til andre metoder og aktivere dem på et senere tidspunkt.
Signaturen for en stedfortræder definerer parametrene og returtypen for de metoder, der kan tildeles til den. Det betyder, at du kan oprette en stedfortrædertype, der svarer til signaturen for en metode, og derefter tildele en hvilken som helst metode med denne signatur til stedfortræderen. Denne funktion giver dig mulighed for at kalde metoden via stedfortræderen, selvom du ikke ved, hvilken metode den er på kompileringstidspunktet.
I følgende eksempel kan du se, hvordan du definerer en stedfortrædertype:
public delegate int PerformCalculation(int x, int y);
I dette eksempel defineres en stedfortræder med navnet PerformCalculation. Stedfortræderen PerformCalculation er defineret til at repræsentere metoder, der tager to int parametre (x og y) og returnerer en int. Denne stedfortræder kan bruges til at indkapsle metoder, der udfører forskellige beregninger, f.eks. addition, subtraktion, multiplikation, division eller mere komplekse ligninger, der bruger de to parametre.
Denne stedfortræder kan f.eks. bruges til at indkapsle følgende metoder:
public class Calculator
{
public int Add(int x, int y)
{
return x + y;
}
public int Subtract(int x, int y)
{
return x - y;
}
public int Multiply(int x, int y)
{
return x * y;
}
public int Divide(int x, int y)
{
if (y == 0)
throw new DivideByZeroException();
return x / y;
}
}
Dette eksempel definerer en Calculator klasse, der indeholder metoder, der svarer til stedfortræderens PerformCalculation signatur. Du kan oprette forekomster af stedfortræderen og tildele dem til forskellige metoder, så du kan kalde den relevante metode på kørselstidspunktet baseret på dine behov.
Følgende kode viser, hvordan du bruger stedfortræderen PerformCalculation :
public class Program
{
public static void Main()
{
Calculator calculator = new Calculator();
// Create delegate instances
PerformCalculation add = new PerformCalculation(calculator.Add);
PerformCalculation subtract = new PerformCalculation(calculator.Subtract);
PerformCalculation multiply = new PerformCalculation(calculator.Multiply);
PerformCalculation divide = new PerformCalculation(calculator.Divide);
// Call the methods using the delegates
Console.WriteLine("Addition: " + add(5, 3)); // Output: 8
Console.WriteLine("Subtraction: " + subtract(5, 3)); // Output: 2
Console.WriteLine("Multiplication: " + multiply(5, 3)); // Output: 15
Console.WriteLine("Division: " + divide(5, 3)); // Output: 1
}
}
I dette eksempel oprettes der en forekomst af Calculator klassen, og metoderne tildeles forekomster af stedfortræderen PerformCalculation . Metoderne kaldes derefter ved hjælp af stedfortræderforekomsterne, så du kan udføre forskellige beregninger baseret på den tildelte stedfortræder.
Egenskaber for stedfortrædertype
Stedfortrædere er referencetyper, hvilket betyder, at de er gemt på heap'en og kan overføres som ethvert andet objekt. Når du opretter en stedfortræderforekomst, opretter du et objekt, der indkapsler en metode. Denne indkapsling giver dig mulighed for at behandle stedfortræderen som et førsteklasses objekt på samme måde som ethvert andet objekt i C#. Du kan oprette forekomster af stedfortrædere, tildele dem til variabler og overføre dem som argumenter til metoder. Processen ligner den måde, du arbejder med andre objekter på i C#, f.eks. strenge eller lister.
Stedfortrædertyper er forseglet, de kan ikke afledes af, og det er ikke muligt at udlede brugerdefinerede klasser fra klassen Delegate . Stedfortrædere er også uforanderlige, hvilket betyder, at når en stedfortræder er oprettet, kan du ikke ændre den metode, den indkapsler. Du kan dog oprette nye stedfortræderforekomster, der peger på forskellige metoder. Denne uforanderlighed sikrer, at stedfortræderen altid peger på den samme metode, hvilket er vigtigt for at bevare kodens integritet.
Du kalder en forekomst af stedfortræderen som en metode, og den aktiverer den metode, den indkapsler.
Stedfortrædere har følgende egenskaber:
- Stedfortrædere giver dig mulighed for at overføre metoder som argumenter til andre metoder.
- Stedfortrædere kan kædes sammen, f.eks. ved at kalde flere metoder for en enkelt hændelse.
- Stedfortrædere er typesikre, hvilket betyder, at compileren kontrollerer, at en metodesignatur stemmer overens med stedfortrædersignaturen på kompileringstidspunktet.
Bemærk
Metoder behøver ikke at stemme nøjagtigt overens med stedfortrædertypen. Hvis metodesignaturen er kompatibel, tillader compileren, at metoden tildeles til stedfortræderen. Denne funktionsmåde kaldes kovarians og kontravarians. Kovarians giver dig mulighed for at bruge en mere afledt type end oprindeligt angivet, mens contravariance giver dig mulighed for at bruge en mindre afledt type. Denne funktion er nyttig, når du arbejder med nedarvning og polymorfi, da den giver dig mulighed for at oprette mere fleksibel kode, der kan genbruges. Variansen undersøges i en separat enhed i dette modul.
Hvorfor bruge stedfortrædere?
Stedfortrædere tilbyder flere fordele i forhold til direkte metodekald og løser flere vigtige problemer, der er relateret til kodefleksibilitet, dynamisk metodeaktivering og typesikkerhed.
Stedfortrædere giver mange fordele, herunder følgende elementer:
- Fleksibilitet: Stedfortrædere giver dig mulighed for at overføre forskellige metoder som parametre og aktivere dynamisk funktionsmåde baseret på kørselsbetingelser. Denne fleksibilitet er nyttig, når den nøjagtige handling, der skal udføres, bestemmes på kørselstidspunktet.
- Udvidelse: Med stedfortrædere kan du nemt udvide funktionaliteten ved at tilføje nye handlinger uden at ændre den eksisterende kode. Du kan overføre en hvilken som helst metode, der svarer til stedfortrædersignaturen.
- Afkobling: Stedfortrædere afkobler metodens aktivering fra metodedefinitionen, hvilket gør koden mere modulopbygget og nemmere at vedligeholde.
Stedfortrædere er en effektiv funktion i C#, der løser flere almindelige problemer i programmeringen. De giver en fleksibel og typesikker måde at indkapsle metoder på, hvilket muliggør aktivering af dynamiske metoder, tilbagekaldsmetoder og multicast-aktivering. Ved hjælp af stedfortrædere kan du skrive mere kode, der kan genbruges og vedligeholdes, og som kan tilpasses de ændrede krav.
Aktivering af dynamisk metode
Muligheden for dynamisk at aktivere metoder på kørselstidspunktet er en effektiv funktion for stedfortrædere. Aktivering af dynamiske metoder giver dig mulighed for at skrive mere fleksibel og genbrugelig kode, da du kan overføre forskellige metoder som parametre uden at kende deres nøjagtige implementering på kompileringstidspunktet.
Scenarie: Forestil dig, at du har en liste over kunder, og at du skal sortere dem efter forskellige kriterier, f.eks. navn, kontotype eller kunde-id. Uden stedfortrædere skal du skrive separate sorteringsmetoder for hvert kriterium, hvilket fører til gentagen og mindre vedligeholdbar kode.
Løsning: Stedfortrædere giver dig mulighed for at overføre metoder som parametre og aktivere aktivering af dynamiske metoder. Du kan definere en stedfortræder, der svarer til signaturen for sorteringsmetoden, og overføre forskellige sammenligningsfunktioner på kørselstidspunktet. Det gør din kode mere fleksibel og kan genbruges.
Tilbagekaldsmetoder
Behovet for tilbagekaldsmetoder opstår i scenarier, hvor du vil udføre en handling, når en bestemt handling er fuldført. Tilbagekaldsmønsteret er almindeligt i asynkron programmering, hvor du måske vil give brugeren besked eller udføre andre handlinger, når en opgave, der har kørt i lang tid, er fuldført.
Scenarie: I asynkron programmering skal du ofte udføre andre handlinger, når en handling er fuldført. Uden stedfortrædere skal du knytte den asynkrone handling tæt til opfølgningshandlinger, hvilket reducerer fleksibiliteten og gør det sværere at vedligeholde koden.
Løsning: Stedfortrædere aktiverer implementeringen af tilbagekaldsmetoder, så du kan angive opfølgningshandlinger dynamisk. Dette afkobler den asynkrone handling fra tilbagekaldslogikken, hvilket øger fleksibiliteten og vedligeholdelsen.
Typesikkerhed
Typesikkerhed er et afgørende aspekt ved programmering, der sikrer, at de metoder, du aktiverer, stemmer overens med de forventede signaturer. Dette forhindrer kørselsfejl og gør din kode mere robust.
Scenarie: Når du overfører metoder som parametre eller gemmer dem til senere aktivering, skal du sikre, at metodesignaturerne stemmer overens. Uden stedfortrædere ville du mangle typesikkerhed, hvilket førte til potentielle kørselsfejl og mindre robust kode.
Løsning: Stedfortrædere leverer typesikre metodereferencer, der sikrer, at metodesignaturerne stemmer overens med stedfortrædersignaturen. Dette forhindrer kørselsfejl og gør koden mere robust.
Multicast-aktivering
Multicast-aktivering er en funktion i stedfortrædere, der giver dig mulighed for at aktivere flere metoder med en enkelt stedfortræder. Denne funktion er nyttig i scenarier til hændelseshåndtering, hvor du vil give flere hændelsesabonenter besked om en forekomst.
Scenarie: I hændelseshåndtering skal du ofte give flere abonnenter besked om en forekomst. Uden stedfortrædere skal du manuelt administrere listen over abonnenter og aktivere deres metoder, hvilket fører til kompleks og fejlbehæftet kode.
Løsning: Stedfortrædere understøtter multicast-aktivering, så en enkelt stedfortræder kan referere til flere metoder. Dette forenkler hændelseshåndteringen ved automatisk at administrere listen over abonnenter og aktivere deres metoder i rækkefølge.
Bedste praksis for erklæring af stedfortrædere i C#
Når du føjer stedfortrædere til en klasse, er det vigtigt at følge bedste praksis for at sikre, at din kode er organiseret, læsbar og kan vedligeholdes. Her er nogle retningslinjer for, hvor du kan definere stedfortrædere:
Definer stedfortrædere øverst i en klassefil
Det er almindelig praksis for udviklere at deklarere stedfortrædere øverst i en fil, typisk inden for navneområdet, men uden for en hvilken som helst klasse. Denne fremgangsmåde gør det nemt at finde stedfortræderdefinitionerne og forstå deres formål. Det giver dig også mulighed for at definere stedfortrædere, der kan bruges af flere klasser inden for det samme navneområde.
Følgende kode viser, hvordan du implementerer en stedfortræder, der er defineret uden for en klasse:
namespace MyNamespace
// Define the delegate outside the class
public delegate void MyDelegate(string message);
public class Publisher
{
// Method that uses the delegate
public void PublishMessage(MyDelegate del)
{
del("Hello from Publisher!");
}
}
public class Subscriber
{
public void Subscribe()
{
// Create an instance of the Publisher class
Publisher publisher = new Publisher();
// Create an instance of the delegate and pass a method to it
MyDelegate del = new MyDelegate(PrintMessage);
// Call the method of the Publisher class and pass the delegate
publisher.PublishMessage(del);
}
// Method that matches the delegate signature
public void PrintMessage(string message)
{
Console.WriteLine(message);
}
}
Definer stedfortrædere i en klasse
Hvis en stedfortræder er specifik for en klasse og ikke er beregnet til at blive brugt uden for klassen, kan du definere stedfortræderen i klassen. Dette indkapsler stedfortræderen i klassen, hvilket er nyttigt, når stedfortræderen er tæt relateret til klassens funktionalitet og ikke er beregnet til brug uden for denne kontekst. Hvis stedfortræderen er offentlig, kan andre klasser i det samme navneområde få adgang til stedfortræderen ved hjælp af en forekomst af klassen.
namespace MyNamespace
public class Publisher
{
// Define a public delegate
public delegate void MyDelegate(string message);
// Method that uses the delegate
public void PublishMessage(MyDelegate del)
{
del("Hello from Publisher!");
}
}
public class Subscriber
{
public void Subscribe()
{
// Create an instance of the Publisher class
Publisher publisher = new Publisher();
// Create an instance of the delegate and pass a method to it
Publisher.MyDelegate del = new Publisher.MyDelegate(PrintMessage);
// Call the method of the Publisher class and pass the delegate
publisher.PublishMessage(del);
}
// Method that matches the delegate signature
public void PrintMessage(string message)
{
Console.WriteLine(message);
}
}
Nøglepunkter
- Stedfortrædere er .NET-typer, der er afledt af den
Delegateklasse, der indkapsler metoder. - Stedfortrædere giver dig mulighed for at overføre metoder som parametre, gemme dem i variabler og aktivere dem på kørselstidspunktet.
- Stedfortrædere er typesikre, hvilket betyder, at compileren kontrollerer, at metodesignaturerne stemmer overens med stedfortrædersignaturen på kompileringstidspunktet.
- Stedfortrædere kan bruges til aktivering af dynamiske metoder, tilbagekaldsmetoder, typesikkerhed og multicast-aktivering.
- Stedfortrædere er grundlaget for hændelseshåndtering i C#.
- Stedfortrædere kan kædes sammen, så flere metoder kan aktiveres med en enkelt stedfortræder.
- Stedfortrædere defineres typisk uden for en klasse for at give adgang fra andre klasser uden at skulle instantiere klassen.