Anteckning
Å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.
Obs
Den här artikeln är en funktionsspecifikation. Specifikationen fungerar som designdokument för funktionen. Den innehåller föreslagna specifikationsändringar, tillsammans med information som behövs under utformningen och utvecklingen av funktionen. Dessa artiklar publiceras tills de föreslagna specifikationsändringarna har slutförts och införlivats i den aktuella ECMA-specifikationen.
Det kan finnas vissa skillnader mellan funktionsspecifikationen och den slutförda implementeringen. Dessa skillnader fångas upp i de relevanta LDM-anteckningarna.
Du kan läsa mer om processen för att införa funktionsspecifikationer i C#-språkstandarden i artikeln om specifikationerna.
Champion-problem: https://github.com/dotnet/csharplang/issues/3435
Sammanfattning
Gör att du kan matcha en matris eller en lista med en sekvens med mönster, t.ex. array is [1, 2, 3] matchar en heltalsmatris med längden tre med 1, 2, 3 som element.
Detaljerad design
Mönstersyntaxen ändras enligt följande:
list_pattern_clause
  : '[' (pattern (',' pattern)* ','?)? ']'
  ;
list_pattern
  : list_pattern_clause simple_designation?
  ;
slice_pattern
  : '..' pattern?
  ;
primary_pattern
  : list_pattern
  | slice_pattern
  | // all of the pattern forms previously defined
  ;
Det finns två nya mönster:
- list_pattern används för att matcha element.
- En slice_pattern tillåts bara en gång och endast direkt i en list_pattern_clause och tar bort noll eller fler element.
Mönsterkompatibilitet
En list_pattern är kompatibel med alla typer som kan räknas samt indexerbara – den har en tillgänglig indexerare som tar en Index som argument eller på annat sätt en tillgänglig indexerare med en enda int parameter. Om båda indexerarna finns är det förstnämnda att föredra.
En slice_pattern med ett underavsnitt är kompatibelt med alla typer som kan räknas samt utsnittsbara – den har en tillgänglig indexerare som tar en Range som argument eller på annat sätt en tillgänglig Slice metod med två int parametrar. Om båda är närvarande är det förstnämnda att föredra.
En slice_pattern utan underavsnitt är kompatibel med alla typer som är kompatibla med en list_pattern.
Den här uppsättningen regler härleds från range indexer-mönstret.
Kontroll av subsumtion
Undersumtionskontroll fungerar precis som positionsmönster med ITuple – motsvarande undermönster matchas efter position plus ytterligare en nod för testlängd.
Följande kod genererar till exempel ett fel eftersom båda mönstren ger samma DAG:
case [_, .., 1]: // expr.Length is >= 2 && expr[^1] is 1
case [.., _, 1]: // expr.Length is >= 2 && expr[^1] is 1
Till skillnad från
case [_, 1, ..]: // expr.Length is >= 2 && expr[1] is 1
case [.., 1, _]: // expr.Length is >= 2 && expr[^2] is 1
Ordningen i vilken undermönster matchas vid körning är ospecificerad, och en misslyckad matchning behöver inte försöka matcha alla undermönster.
Givet en viss längd är det möjligt att två delmönster refererar till samma element, i vilket fall ett test för det här värdet infogas i beslutsdiagrammet.
- Till exempel blir [_, >0, ..] or [.., <=0, _]length >= 2 && ([1] > 0 || length == 3 || [^2] <= 0)där längdvärdet 3 innebär det andra testet.
- Omvänt blir [_, >0, ..] and [.., <=0, _]length >= 2 && [1] > 0 && length != 3 && [^2] <= 0där längdvärdet 3 inte tillåter det andra testet.
Som ett resultat uppstår ett fel för något som case [.., p]: case [p]:, eftersom vi behandlar samma element vid körning av programmet i det andra fallet.
Om ett segmentundermönster matchar en lista eller ett längdvärde behandlas undermönster som om de vore ett direkt undermönster i den innehållande listan. Till exempel omfattar [..[1, 2, 3]] ett mönster av formen [1, 2, 3].
Följande antaganden görs om de medlemmar som används:
- Egenskapen som gör typen countable antas alltid returnera ett icke-negativt värde, om och endast om typen är indexerbar. Mönstret { Length: -1 }kan till exempel aldrig matcha en matris.
- Den medlemsvariabel som gör typen utsnittsbar antas vara korrekt fungerande, det vill säga returvärdet är aldrig null och att det är en korrekt del av den innehållande listan.
Beteendet för en mönstermatchningsåtgärd är odefinierat om något av ovanstående antaganden inte gäller.
Sänka
Ett mönster i formuläret expr is [1, 2, 3] motsvarar följande kod:
expr.Length is 3
&& expr[new Index(0, fromEnd: false)] is 1
&& expr[new Index(1, fromEnd: false)] is 2
&& expr[new Index(2, fromEnd: false)] is 3
En slice_pattern fungerar som en korrekt borttagning, dvs. inga tester kommer att genereras för ett sådant mönster, utan påverkar det bara andra noder, nämligen längden och indexeraren. Ett mönster i formuläret expr is [1, .. var s, 3] motsvarar till exempel följande kod (om det är kompatibelt via explicit Index och Range stöd):
expr.Length is >= 2
&& expr[new Index(0, fromEnd: false)] is 1
&& expr[new Range(new Index(1, fromEnd: false), new Index(1, fromEnd: true))] is var s
&& expr[new Index(1, fromEnd: true)] is 3
Den indatatypen för slice_pattern är returtypen för den underliggande this[Range]- eller Slice-metoden med två undantag: För string och matriser används string.Substring respektive RuntimeHelpers.GetSubArray.
Olösta frågor
- Ska vi stödja flerdimensionella matriser? (svar [LDM 2021-05-26]: Stöds inte. Om vi vill göra en allmän MD-matrisfokuserad version vill vi gå tillbaka till alla områden som de för närvarande saknar, inte bara listmönster.)
- Ska vi acceptera ett allmänt mönster efter ..i en slice_pattern? (svar [LDM 2021-05-26]: Ja, alla mönster är tillåtna efter en del.)
- Enligt den här definitionen testar mönstret [..]förexpr.Length >= 0. Bör vi utelämna ett sådant test, förutsatt attLengthalltid är icke-negativ? (svar [LDM 2021-05-26]:[..]kommer inte att utföra en längdkontroll)
C# feature specifications