Kommentar
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Tip
Den här artikeln är en del av avsnittet Grunderna för utvecklare som redan känner till minst ett programmeringsspråk och lär sig C#. Börja med mönstermatchningsöversikten om mönster är nya för dig. Fullständiga kompatibilitetsregler finns i deklarations- och typmönster i språkreferensen.
Ett typmönster tillämpas på ett indatauttryck. C# utvärderar uttrycket och testar sedan om det resulterande värdet inte är null och dess körningstyp är kompatibel med den angivna typen. Ett typmönster rapporterar endast om typtestet lyckas. Den deklarerar inte en variabel.
Ställ en fråga med ja- eller nej-svar
I ett leveranssystem IRouteStop är ett kapacitetskontrakt för destinationer som accepteras av ruttplaneringen.
CanRoute testar om det utvärderade målet har den funktionen och dess booleska resultat avgör om målet kommer in i arbetsflödet för routningsplanering. Arbetsflödet behöver bara ett ja-or-no svar och läser inga route-stop-medlemmar, så ett typmönster utan en infångad variabel passar.
static bool CanRoute(object? destination) =>
destination is IRouteStop;
Indatauttrycket är destination, och IRouteStop är den typ som testas. Välj ett typmönster när svaret bara är ja eller nej. Om den matchande grenen behöver läsa en adress eller anropa en annan medlem via IRouteStopväljer du ett deklarationsmönster i stället så att grenen har en variabel av den typen.
Note
Du kan också se destination is IRouteStop _. Syntaxen är ett deklarationsmönster som _ innebär att ingen variabel behålls. Det utför samma typ av test när båda formerna är giltiga, men destination is IRouteStop uttrycker tydligare avsikten att det endast gäller test.
Matcha klasser och gränssnitt
I leveranssystemet IRouteStop definierar kapacitetskontraktet för routningsplaneringsmål, medan RouteStop är en basklass som tillhandahåller vanliga vägstoppsdata och implementering.
ExpressRouteStop är en specialiserad klass härledd från RouteStop. Exemplet testar ett utvärderat värde så att dess utdata kan demonstrera alla tre kompatibla typerna. Varje test behöver bara ett booleskt resultat, så ingen infångad variabel behövs.
interface IRouteStop { }
abstract class RouteStop(string street) : IRouteStop
{
public string Street { get; } = street;
public string GetDisplayName() => Street;
}
sealed class ExpressRouteStop(string street) : RouteStop(street)
{
}
static void ShowCompatibility()
{
object destination = new ExpressRouteStop("8 Oak Avenue");
Console.WriteLine($"Exact class: {destination is ExpressRouteStop}");
Console.WriteLine($"Base class: {destination is RouteStop}");
Console.WriteLine($"Interface: {destination is IRouteStop}");
}
Det utvärderade värdet är en ExpressRouteStop. Resultatet visar att den matchar sin exakta klass, dess basklass RouteStop och gränssnittet IRouteStop som RouteStop implementerar.
Detaljerade kompatibilitetsregler och gränsfall finns i typmönsterreferensen.
Routa flera typer
I ett supportsystem SupportRequest är basklassen för specialiserade begärandeklasser som PasswordResetRequest och BillingQuestion. En switcharm parar ihop ett mönster med resultatet som ska returneras när det mönstret matchar. Varje arm returnerar namnet på en bearbetningskö och den sista armen tillhandahåller en reservkö för andra utvärderade värden. Den valda kön beror bara på körtidstypen för det utvärderade värdet, så typmönster fungerar eftersom ingen medlem i begäran läses.
static string RouteRequest(object request) =>
request switch
{
PasswordResetRequest => "Identity queue",
BillingQuestion => "Billing queue",
SupportRequest => "General support queue",
_ => "Intake queue"
};
Varje arm besvarar en fråga om typ och returnerar den kö som hanterar den förfrågan. Om en arm behöver läsa medlemmar i begäran använder du ett deklarationsmönster för att fånga det matchande värdet i en variabel.
Omkopplingsarmarna betraktas uppifrån och ner. Placera en specialiserad klass före basklassen. Annars kan basklassarmen matcha varje instans av den specialiserade klassen, vilket gör att den senare armen inte kan nås.
Valfritt: Använd en typparameter som testad typ
Det här valfria exemplet bygger på generiska typer och metoder. En typparameter som TRequest är en platshållare för en typ som anroparen tillhandahåller. En batch för inkommande begäran kan innehålla flera typer av begäranden och anroparen tillhandahåller ConfidentialRequest för att testa om en begäran kräver konfidentiell hantering. Det booleska resultatet väljer konfidentiell hantering för hela batchen och skapar ett synligt statusmeddelande. Ett typmönster med en typparameter passar eftersom endast förekomsten av en matchande begäran är viktig, så det matchande objektet behöver inte behållas.
static void ShowConfidentialBatchHandling()
{
object[] incomingRequests = [new BillingQuestion(), new ConfidentialRequest()];
bool requiresConfidentialHandling =
ContainsRequestOfType<ConfidentialRequest>(incomingRequests);
Console.WriteLine(requiresConfidentialHandling
? "Send the entire batch to confidential handling."
: "Send the batch to standard handling.");
}
static bool ContainsRequestOfType<TRequest>(IEnumerable<object> requests)
{
foreach (object request in requests)
{
if (request is TRequest)
{
return true;
}
}
return false;
}
Om anroparen behövde själva matchningsbegäran skulle en sök- eller filteråtgärd som returnerar matchande objekt vara lämpligare.