Patroonkoppeling - de is
en switch
expressies, en operatoren and
, or
en not
in patronen
U gebruikt de is
expressie, de switchinstructie en de switchexpressie om een invoerexpressie te vergelijken met een willekeurig aantal kenmerken. C# ondersteunt meerdere patronen, waaronder declaratie, type, constante, relationeel, eigenschap, lijst, var en verwijderen. Patronen kunnen worden gecombineerd met booleaanse logische trefwoorden and
, or
en not
.
De volgende C#-expressies en -instructies ondersteunen patroonkoppeling:
In deze constructies kunt u een invoerexpressie vergelijken met een van de volgende patronen:
- Declaratiepatroon: als u het uitvoeringstype van een expressie wilt controleren en, als een overeenkomst slaagt, wijst u een expressieresultaat toe aan een gedeclareerde variabele.
- Typepatroon: om het runtimetype van een expressie te controleren.
- Constant patroon: om te testen of een expressieresultaat gelijk is aan een opgegeven constante.
- Relationele patronen: een expressieresultaat vergelijken met een opgegeven constante.
- Logische patronen: om te testen of een expressie overeenkomt met een logische combinatie van patronen.
- Eigenschapspatroon: om te testen of de eigenschappen of velden van een expressie overeenkomen met geneste patronen.
- Positioneel patroon: om een expressieresultaat te deconstrueren en te testen of de resulterende waarden overeenkomen met geneste patronen.
var
patroon: om een expressie overeen te laten komen en het resultaat toe te wijzen aan een gedeclareerde variabele.- Patroon verwijderen: om een expressie te vinden.
- Lijstpatronen: om te testen of reekselementen overeenkomen met overeenkomende geneste patronen. Geïntroduceerd in C# 11.
Logische, eigenschaps-, positionele en lijstpatronen zijn recursieve patronen. Dat wil gezegd, ze kunnen geneste patronen bevatten.
Zie Zelfstudie: Patroonkoppeling gebruiken om typegestuurde en gegevensgestuurde algoritmen te bouwen voor het gebruik van deze patronen.
Declaratie- en typepatronen
U gebruikt declaratie- en typepatronen om te controleren of het runtimetype van een expressie compatibel is met een bepaald type. Met een declaratiepatroon kunt u ook een nieuwe lokale variabele declareren. Wanneer een declaratiepatroon overeenkomt met een expressie, wordt aan die variabele een geconverteerd expressieresultaat toegewezen, zoals in het volgende voorbeeld wordt weergegeven:
object greeting = "Hello, World!";
if (greeting is string message)
{
Console.WriteLine(message.ToLower()); // output: hello, world!
}
Een declaratiepatroon met type T
komt overeen met een expressie wanneer een expressieresultaat niet null is en een van de volgende voorwaarden waar is:
Het uitvoeringstype van een expressieresultaat is
T
.Het uitvoeringstype van een expressieresultaat is afgeleid van het type
T
, implementeert interfaceT
of een andere impliciete verwijzingsconversie bestaat van daaruitT
. In het volgende voorbeeld ziet u twee gevallen waarin aan deze voorwaarde wordt voldaan:var numbers = new int[] { 10, 20, 30 }; Console.WriteLine(GetSourceLabel(numbers)); // output: 1 var letters = new List<char> { 'a', 'b', 'c', 'd' }; Console.WriteLine(GetSourceLabel(letters)); // output: 2 static int GetSourceLabel<T>(IEnumerable<T> source) => source switch { Array array => 1, ICollection<T> collection => 2, _ => 3, };
In het voorgaande voorbeeld komt bij de eerste aanroep van de
GetSourceLabel
methode het eerste patroon overeen met een argumentwaarde omdat het runtimetypeint[]
van het argument is afgeleid van het Array type. Bij de tweede aanroep van deGetSourceLabel
methode wordt het runtimetype List<T> van het argument niet afgeleid van het Array type, maar wordt de ICollection<T> interface geïmplementeerd.Het uitvoeringstype van een expressieresultaat is een null-waardetype met het onderliggende type
T
.Er bestaat een conversie van boksen of het uitboxen van het uitvoeringstype van een expressieresultaat dat moet worden getypt
T
.
In het volgende voorbeeld ziet u de laatste twee voorwaarden:
int? xNullable = 7;
int y = 23;
object yBoxed = y;
if (xNullable is int a && yBoxed is int b)
{
Console.WriteLine(a + b); // output: 30
}
Als u alleen het type expressie wilt controleren, kunt u een verwijdering _
gebruiken in plaats van de naam van een variabele, zoals in het volgende voorbeeld wordt weergegeven:
public abstract class Vehicle {}
public class Car : Vehicle {}
public class Truck : Vehicle {}
public static class TollCalculator
{
public static decimal CalculateToll(this Vehicle vehicle) => vehicle switch
{
Car _ => 2.00m,
Truck _ => 7.50m,
null => throw new ArgumentNullException(nameof(vehicle)),
_ => throw new ArgumentException("Unknown type of a vehicle", nameof(vehicle)),
};
}
Hiervoor kunt u een typepatroon gebruiken, zoals in het volgende voorbeeld wordt weergegeven:
public static decimal CalculateToll(this Vehicle vehicle) => vehicle switch
{
Car => 2.00m,
Truck => 7.50m,
null => throw new ArgumentNullException(nameof(vehicle)),
_ => throw new ArgumentException("Unknown type of a vehicle", nameof(vehicle)),
};
Net als bij een declaratiepatroon komt een typepatroon overeen met een expressie wanneer een expressieresultaat niet null is en het runtimetype voldoet aan een van de bovenstaande voorwaarden.
Als u wilt controleren op niet-null, kunt u een negatief null
constant patroon gebruiken, zoals in het volgende voorbeeld wordt weergegeven:
if (input is not null)
{
// ...
}
Zie de secties Declaratiepatroon en Typepatroon van de notities van het functievoorstel voor meer informatie.
Constant patroon
U gebruikt een constant patroon om te testen of een expressieresultaat gelijk is aan een opgegeven constante, zoals in het volgende voorbeeld wordt weergegeven:
public static decimal GetGroupTicketPrice(int visitorCount) => visitorCount switch
{
1 => 12.0m,
2 => 20.0m,
3 => 27.0m,
4 => 32.0m,
0 => 0.0m,
_ => throw new ArgumentException($"Not supported number of visitors: {visitorCount}", nameof(visitorCount)),
};
In een constant patroon kunt u elke constante expressie gebruiken, zoals:
- een geheel getal of numerieke letterlijke drijvende komma
- een teken
- een letterlijke tekenreeks .
- een Booleaanse waarde
true
offalse
- een opsommingswaarde
- de naam van een gedeclareerd const-veld of lokaal
null
De expressie moet een type zijn dat converteert naar het constante type, met één uitzondering: een expressie waarvan het type is Span<char>
of ReadOnlySpan<char>
kan worden vergeleken met constante tekenreeksen in C# 11 en latere versies.
Gebruik een constant patroon om te controleren null
op, zoals in het volgende voorbeeld wordt weergegeven:
if (input is null)
{
return;
}
De compiler garandeert dat er geen door de gebruiker overbelaste gelijkheidsoperator ==
wordt aangeroepen wanneer de expressie x is null
wordt geëvalueerd.
U kunt een negatief null
constant patroon gebruiken om te controleren op niet-null, zoals in het volgende voorbeeld wordt weergegeven:
if (input is not null)
{
// ...
}
Zie de sectie Constant patroon van de notitie van het functievoorstel voor meer informatie.
Relationele patronen
U gebruikt een relationeel patroon om een expressieresultaat te vergelijken met een constante, zoals in het volgende voorbeeld wordt weergegeven:
Console.WriteLine(Classify(13)); // output: Too high
Console.WriteLine(Classify(double.NaN)); // output: Unknown
Console.WriteLine(Classify(2.4)); // output: Acceptable
static string Classify(double measurement) => measurement switch
{
< -4.0 => "Too low",
> 10.0 => "Too high",
double.NaN => "Unknown",
_ => "Acceptable",
};
In een relationeel patroon kunt u een van de relationele operatoren <
, >
of <=
>=
. Het rechterdeel van een relationeel patroon moet een constante expressie zijn. De constante expressie kan van een geheel getal, drijvende komma, teken of opsommingstype zijn.
Als u wilt controleren of een expressieresultaat zich in een bepaald bereik bevindt, moet u dit vergelijken met een voorwaardef and
patroon, zoals in het volgende voorbeeld wordt weergegeven:
Console.WriteLine(GetCalendarSeason(new DateTime(2021, 3, 14))); // output: spring
Console.WriteLine(GetCalendarSeason(new DateTime(2021, 7, 19))); // output: summer
Console.WriteLine(GetCalendarSeason(new DateTime(2021, 2, 17))); // output: winter
static string GetCalendarSeason(DateTime date) => date.Month switch
{
>= 3 and < 6 => "spring",
>= 6 and < 9 => "summer",
>= 9 and < 12 => "autumn",
12 or (>= 1 and < 3) => "winter",
_ => throw new ArgumentOutOfRangeException(nameof(date), $"Date with unexpected month: {date.Month}."),
};
Als een expressieresultaat is null
of niet kan worden geconverteerd naar het type constante door een null-conversie of het ongedaan maken van de conversie, komt een relationeel patroon niet overeen met een expressie.
Zie de sectie Relationele patronen van de notitie van het functievoorstel voor meer informatie.
Logische patronen
U gebruikt de not
combinaties van , and
en or
patrooncombinaties om de volgende logische patronen te maken:
Negatiepatroon
not
dat overeenkomt met een expressie wanneer het negated patroon niet overeenkomt met de expressie. In het volgende voorbeeld ziet u hoe u een constantnull
patroon kunt om te controleren of een expressie niet null is:if (input is not null) { // ... }
Dit patroon
and
komt overeen met een expressie wanneer beide patronen overeenkomen met de expressie. In het volgende voorbeeld ziet u hoe u relationele patronen kunt combineren om te controleren of een waarde zich in een bepaald bereik bevindt:Console.WriteLine(Classify(13)); // output: High Console.WriteLine(Classify(-100)); // output: Too low Console.WriteLine(Classify(5.7)); // output: Acceptable static string Classify(double measurement) => measurement switch { < -40.0 => "Too low", >= -40.0 and < 0 => "Low", >= 0 and < 10.0 => "Acceptable", >= 10.0 and < 20.0 => "High", >= 20.0 => "Too high", double.NaN => "Unknown", };
Disjunctive-patroon
or
dat overeenkomt met een expressie wanneer een van beide patronen overeenkomt met de expressie, zoals in het volgende voorbeeld wordt weergegeven:Console.WriteLine(GetCalendarSeason(new DateTime(2021, 1, 19))); // output: winter Console.WriteLine(GetCalendarSeason(new DateTime(2021, 10, 9))); // output: autumn Console.WriteLine(GetCalendarSeason(new DateTime(2021, 5, 11))); // output: spring static string GetCalendarSeason(DateTime date) => date.Month switch { 3 or 4 or 5 => "spring", 6 or 7 or 8 => "summer", 9 or 10 or 11 => "autumn", 12 or 1 or 2 => "winter", _ => throw new ArgumentOutOfRangeException(nameof(date), $"Date with unexpected month: {date.Month}."), };
Zoals in het voorgaande voorbeeld wordt weergegeven, kunt u herhaaldelijk de patrooncombinaties in een patroon gebruiken.
Prioriteit en volgorde van controle
De patrooncombinaties worden als volgt geordend van de hoogste prioriteit tot de laagste:
not
and
or
Wanneer een logisch patroon een patroon van een is
expressie is, is de prioriteit van combinaties van logische patronen hoger dan de prioriteit van logische operators (zowel bitsgewijze logische als Booleaanse logische operators). Anders is de prioriteit van combinaties van logische patronen lager dan de prioriteit van logische en voorwaardelijke logische operators. Zie de sectie Operatorprioriteit van het artikel C#-operators voor de volledige lijst met C#-operators die zijn gerangschikt op prioriteitsniveau.
Als u expliciet de prioriteit wilt opgeven, gebruikt u haakjes, zoals in het volgende voorbeeld wordt weergegeven:
static bool IsLetter(char c) => c is (>= 'a' and <= 'z') or (>= 'A' and <= 'Z');
Notitie
De volgorde waarin patronen worden gecontroleerd, is niet gedefinieerd. Tijdens runtime kunnen de juiste geneste patronen en or
and
patronen eerst worden gecontroleerd.
Zie de sectie Patrooncombinaties van de notitie over het functievoorstel voor meer informatie.
Eigenschapspatroon
U gebruikt een eigenschapspatroon om de eigenschappen of velden van een expressie te vergelijken met geneste patronen, zoals in het volgende voorbeeld wordt weergegeven:
static bool IsConferenceDay(DateTime date) => date is { Year: 2020, Month: 5, Day: 19 or 20 or 21 };
Een eigenschapspatroon komt overeen met een expressie wanneer een expressieresultaat niet null is en elk geneste patroon overeenkomt met de bijbehorende eigenschap of het bijbehorende veld van het expressieresultaat.
U kunt ook een runtime-typecontrole en een variabeledeclaratie toevoegen aan een eigenschapspatroon, zoals in het volgende voorbeeld wordt weergegeven:
Console.WriteLine(TakeFive("Hello, world!")); // output: Hello
Console.WriteLine(TakeFive("Hi!")); // output: Hi!
Console.WriteLine(TakeFive(new[] { '1', '2', '3', '4', '5', '6', '7' })); // output: 12345
Console.WriteLine(TakeFive(new[] { 'a', 'b', 'c' })); // output: abc
static string TakeFive(object input) => input switch
{
string { Length: >= 5 } s => s.Substring(0, 5),
string s => s,
ICollection<char> { Count: >= 5 } symbols => new string(symbols.Take(5).ToArray()),
ICollection<char> symbols => new string(symbols.ToArray()),
null => throw new ArgumentNullException(nameof(input)),
_ => throw new ArgumentException("Not supported input type."),
};
Een eigenschapspatroon is een recursief patroon. Dat wil gezegd, u kunt elk patroon als geneste patroon gebruiken. Gebruik een eigenschapspatroon om delen van gegevens te vergelijken met geneste patronen, zoals in het volgende voorbeeld wordt weergegeven:
public record Point(int X, int Y);
public record Segment(Point Start, Point End);
static bool IsAnyEndOnXAxis(Segment segment) =>
segment is { Start: { Y: 0 } } or { End: { Y: 0 } };
In het voorgaande voorbeeld worden de or
patrooncombinaties en recordtypen gebruikt.
Vanaf C# 10 kunt u verwijzen naar geneste eigenschappen of velden binnen een eigenschapspatroon. Deze mogelijkheid wordt een uitgebreid eigenschapspatroon genoemd. U kunt bijvoorbeeld de methode uit het voorgaande voorbeeld herstructureren in de volgende equivalente code:
static bool IsAnyEndOnXAxis(Segment segment) =>
segment is { Start.Y: 0 } or { End.Y: 0 };
Zie de sectie Eigenschapspatroon van de notitie van het functievoorstel en de notitie voor uitgebreide eigenschappenpatronen voor voorstellen voor meer informatie.
Tip
U kunt de stijlregel Voor het vereenvoudigen van het eigenschapspatroon (IDE0170) gebruiken om de leesbaarheid van code te verbeteren door plaatsen voor te stellen om uitgebreide eigenschapspatronen te gebruiken.
Positioneel patroon
U gebruikt een positioneel patroon om een expressieresultaat te deconstrueren en de resulterende waarden te vergelijken met de bijbehorende geneste patronen, zoals in het volgende voorbeeld wordt weergegeven:
public readonly struct Point
{
public int X { get; }
public int Y { get; }
public Point(int x, int y) => (X, Y) = (x, y);
public void Deconstruct(out int x, out int y) => (x, y) = (X, Y);
}
static string Classify(Point point) => point switch
{
(0, 0) => "Origin",
(1, 0) => "positive X basis end",
(0, 1) => "positive Y basis end",
_ => "Just a point",
};
In het voorgaande voorbeeld bevat het type expressie de deconstructmethode, die wordt gebruikt om een expressieresultaat te deconstrueren .
Belangrijk
De volgorde van leden in een positioneel patroon moet overeenkomen met de volgorde van parameters in de Deconstruct
methode. Dat komt doordat de code die is gegenereerd voor het positionele patroon de Deconstruct
methode aanroept.
U kunt ook expressies van tupletypen vergelijken met positionele patronen. Op die manier kunt u meerdere invoerwaarden vergelijken met verschillende patronen, zoals in het volgende voorbeeld wordt weergegeven:
static decimal GetGroupTicketPriceDiscount(int groupSize, DateTime visitDate)
=> (groupSize, visitDate.DayOfWeek) switch
{
(<= 0, _) => throw new ArgumentException("Group size must be positive."),
(_, DayOfWeek.Saturday or DayOfWeek.Sunday) => 0.0m,
(>= 5 and < 10, DayOfWeek.Monday) => 20.0m,
(>= 10, DayOfWeek.Monday) => 30.0m,
(>= 5 and < 10, _) => 12.0m,
(>= 10, _) => 15.0m,
_ => 0.0m,
};
In het voorgaande voorbeeld worden relationele en logische patronen gebruikt.
U kunt de namen van tuple-elementen en Deconstruct
parameters in een positioneel patroon gebruiken, zoals in het volgende voorbeeld wordt weergegeven:
var numbers = new List<int> { 1, 2, 3 };
if (SumAndCount(numbers) is (Sum: var sum, Count: > 0))
{
Console.WriteLine($"Sum of [{string.Join(" ", numbers)}] is {sum}"); // output: Sum of [1 2 3] is 6
}
static (double Sum, int Count) SumAndCount(IEnumerable<int> numbers)
{
int sum = 0;
int count = 0;
foreach (int number in numbers)
{
sum += number;
count++;
}
return (sum, count);
}
U kunt een positioneel patroon ook op een van de volgende manieren uitbreiden:
Voeg een runtimetypecontrole en een variabeledeclaratie toe, zoals in het volgende voorbeeld wordt weergegeven:
public record Point2D(int X, int Y); public record Point3D(int X, int Y, int Z); static string PrintIfAllCoordinatesArePositive(object point) => point switch { Point2D (> 0, > 0) p => p.ToString(), Point3D (> 0, > 0, > 0) p => p.ToString(), _ => string.Empty, };
In het voorgaande voorbeeld worden positionele records gebruikt die impliciet de
Deconstruct
methode bieden.Gebruik een eigenschapspatroon binnen een positioneel patroon, zoals in het volgende voorbeeld wordt weergegeven:
public record WeightedPoint(int X, int Y) { public double Weight { get; set; } } static bool IsInDomain(WeightedPoint point) => point is (>= 0, >= 0) { Weight: >= 0.0 };
Combineer twee voorgaande gebruiksvoorbeelden, zoals in het volgende voorbeeld wordt weergegeven:
if (input is WeightedPoint (> 0, > 0) { Weight: > 0.0 } p) { // .. }
Een positioneel patroon is een recursief patroon. Dat wil gezegd, u kunt elk patroon als geneste patroon gebruiken.
Zie de sectie Positional pattern van de notitie van het functievoorstel voor meer informatie.
var
patroon
U gebruikt een var
patroon om een expressie, inclusief null
, en het resultaat ervan toe te wijzen aan een nieuwe lokale variabele, zoals in het volgende voorbeeld wordt weergegeven:
static bool IsAcceptable(int id, int absLimit) =>
SimulateDataFetch(id) is var results
&& results.Min() >= -absLimit
&& results.Max() <= absLimit;
static int[] SimulateDataFetch(int id)
{
var rand = new Random();
return Enumerable
.Range(start: 0, count: 5)
.Select(s => rand.Next(minValue: -10, maxValue: 11))
.ToArray();
}
Een var
patroon is handig wanneer u een tijdelijke variabele in een Boole-expressie nodig hebt om het resultaat van tussenliggende berekeningen vast te houden. U kunt ook een var
patroon gebruiken wanneer u meer controles moet uitvoeren in when
gevalbeveiligingen van een switch
expressie of instructie, zoals in het volgende voorbeeld wordt weergegeven:
public record Point(int X, int Y);
static Point Transform(Point point) => point switch
{
var (x, y) when x < y => new Point(-x, y),
var (x, y) when x > y => new Point(x, -y),
var (x, y) => new Point(x, y),
};
static void TestTransform()
{
Console.WriteLine(Transform(new Point(1, 2))); // output: Point { X = -1, Y = 2 }
Console.WriteLine(Transform(new Point(5, 2))); // output: Point { X = 5, Y = -2 }
}
In het voorgaande voorbeeld is het patroon var (x, y)
gelijk aan een positioneel patroon(var x, var y)
.
In een var
patroon is het type van een gedeclareerde variabele het compileertijdtype van de expressie die overeenkomt met het patroon.
Zie de sectie Var-patroon van de notitie van het functievoorstel voor meer informatie.
Patroon negeren
U gebruikt een verwijderingspatroon _
om overeen te komen met een expressie, waaronder null
, zoals in het volgende voorbeeld wordt weergegeven:
Console.WriteLine(GetDiscountInPercent(DayOfWeek.Friday)); // output: 5.0
Console.WriteLine(GetDiscountInPercent(null)); // output: 0.0
Console.WriteLine(GetDiscountInPercent((DayOfWeek)10)); // output: 0.0
static decimal GetDiscountInPercent(DayOfWeek? dayOfWeek) => dayOfWeek switch
{
DayOfWeek.Monday => 0.5m,
DayOfWeek.Tuesday => 12.5m,
DayOfWeek.Wednesday => 7.5m,
DayOfWeek.Thursday => 12.5m,
DayOfWeek.Friday => 5.0m,
DayOfWeek.Saturday => 2.5m,
DayOfWeek.Sunday => 2.0m,
_ => 0.0m,
};
In het voorgaande voorbeeld wordt een verwijderingspatroon gebruikt om alle gehele getallen te verwerken null
die niet het bijbehorende lid van de DayOfWeek opsomming hebben. Dit garandeert dat een switch
expressie in het voorbeeld alle mogelijke invoerwaarden verwerkt. Als u geen verwijderingspatroon in een switch
expressie gebruikt en geen van de patronen van de expressie overeenkomt met een invoer, genereert de runtime een uitzondering. De compiler genereert een waarschuwing als een switch
expressie niet alle mogelijke invoerwaarden verwerkt.
Een verwijderingspatroon kan geen patroon zijn in een is
expressie of een switch
instructie. In dergelijke gevallen gebruikt u een var
patroon met een verwijderingspatroon om een expressie te vinden: var _
. Een verwijderingspatroon kan een patroon in een switch
expressie zijn.
Zie de sectie Patroon negeren van de notitie van het functievoorstel voor meer informatie.
Haakje-patroon
U kunt haakjes rond elk patroon plaatsen. Normaal gesproken doet u dit om de prioriteit in logische patronen te benadrukken of te wijzigen, zoals in het volgende voorbeeld wordt weergegeven:
if (input is not (float or double))
{
return;
}
Lijstpatronen
Vanaf C# 11 kunt u een matrix of lijst vergelijken met een reeks patronen, zoals in het volgende voorbeeld wordt weergegeven:
int[] numbers = { 1, 2, 3 };
Console.WriteLine(numbers is [1, 2, 3]); // True
Console.WriteLine(numbers is [1, 2, 4]); // False
Console.WriteLine(numbers is [1, 2, 3, 4]); // False
Console.WriteLine(numbers is [0 or 1, <= 2, >= 3]); // True
Zoals in het voorgaande voorbeeld wordt weergegeven, wordt een lijstpatroon vergeleken wanneer elk geneste patroon overeenkomt met het bijbehorende element van een invoerreeks. U kunt elk patroon in een lijstpatroon gebruiken. Als u een element wilt vergelijken, gebruikt u het patroon verwijderen of, als u ook het element wilt vastleggen, het var-patroon, zoals in het volgende voorbeeld wordt weergegeven:
List<int> numbers = new() { 1, 2, 3 };
if (numbers is [var first, _, _])
{
Console.WriteLine($"The first element of a three-item list is {first}.");
}
// Output:
// The first element of a three-item list is 1.
De voorgaande voorbeelden komen overeen met een hele invoerreeks op basis van een lijstpatroon. Als u alleen elementen wilt vergelijken aan het begin of/en het einde van een invoerreeks, gebruikt u het segmentpatroon..
, zoals in het volgende voorbeeld wordt weergegeven:
Console.WriteLine(new[] { 1, 2, 3, 4, 5 } is [> 0, > 0, ..]); // True
Console.WriteLine(new[] { 1, 1 } is [_, _, ..]); // True
Console.WriteLine(new[] { 0, 1, 2, 3, 4 } is [> 0, > 0, ..]); // False
Console.WriteLine(new[] { 1 } is [1, 2, ..]); // False
Console.WriteLine(new[] { 1, 2, 3, 4 } is [.., > 0, > 0]); // True
Console.WriteLine(new[] { 2, 4 } is [.., > 0, 2, 4]); // False
Console.WriteLine(new[] { 2, 4 } is [.., 2, 4]); // True
Console.WriteLine(new[] { 1, 2, 3, 4 } is [>= 0, .., 2 or 4]); // True
Console.WriteLine(new[] { 1, 0, 0, 1 } is [1, 0, .., 0, 1]); // True
Console.WriteLine(new[] { 1, 0, 1 } is [1, 0, .., 0, 1]); // False
Een segmentpatroon komt overeen met nul of meer elementen. U kunt maximaal één segmentpatroon in een lijstpatroon gebruiken. Het segmentpatroon kan alleen worden weergegeven in een lijstpatroon.
U kunt ook een subpatroon in een segmentpatroon nesten, zoals in het volgende voorbeeld wordt weergegeven:
void MatchMessage(string message)
{
var result = message is ['a' or 'A', .. var s, 'a' or 'A']
? $"Message {message} matches; inner part is {s}."
: $"Message {message} doesn't match.";
Console.WriteLine(result);
}
MatchMessage("aBBA"); // output: Message aBBA matches; inner part is BB.
MatchMessage("apron"); // output: Message apron doesn't match.
void Validate(int[] numbers)
{
var result = numbers is [< 0, .. { Length: 2 or 4 }, > 0] ? "valid" : "not valid";
Console.WriteLine(result);
}
Validate(new[] { -1, 0, 1 }); // output: not valid
Validate(new[] { -1, 0, 0, 1 }); // output: valid
Zie de notitie van het voorstel voor lijstpatronen voor meer informatie.
C#-taalspecificatie
Zie de sectie Patronen en patroonkoppeling van de C#-taalspecificatie voor meer informatie.
Zie de volgende opmerkingen bij het functievoorstel voor informatie over functies die zijn toegevoegd in C# 8 en hoger:
- Recursieve patroonkoppeling
- Patroonkoppelingsupdates
- C# 10 - Uitgebreide eigenschapspatronen
- C# 11 - Lijstpatronen
- C# 11 - Patroonovereenkomst
Span<char>
voor letterlijke tekenreeks