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, oren 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 interface Tof een andere impliciete verwijzingsconversie bestaat van daaruit T. 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 runtimetype int[] van het argument is afgeleid van het Array type. Bij de tweede aanroep van de GetSourceLabel 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 negatiefnullconstant 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:

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 nullop, 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 negatiefnull 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 notcombinaties van , anden or patrooncombinaties om de volgende logische patronen te maken:

  • Negatiepatroonnot 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 patroonand 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-patroonor 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 logischeals 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 orand 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 orpatrooncombinaties 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 . 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:

Zie ook