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.
Mönstermatch
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 anteckningarna från språkdesignmöten (LDM).
Du kan läsa mer om processen för att införa funktionsspecifikationer i C#-språkstandarden i artikeln om specifikationerna.
Champion-fråga: https://github.com/dotnet/csharplang/issues/8640
Sammanfattning
Tillåt mönster som matchar en Span<char> och en ReadOnlySpan<char> på en konstant sträng.
Motivation
För prestanda prefereras användning av Span<char> och ReadOnlySpan<char> framför strängar i många scenarier. Ramverket har lagt till många nya API:er så att du kan använda ReadOnlySpan<char> i stället för en string.
En vanlig åtgärd på strängar är att använda en växel för att testa om det är ett visst värde, och kompilatorn optimerar en sådan växel. Det finns dock för närvarande inget sätt att göra samma sak på ett ReadOnlySpan<char> effektivt, förutom att implementera växeln och optimeringen manuellt.
För att uppmuntra till införande av ReadOnlySpan<char> tillåter vi mönster som matchar en ReadOnlySpan<char>, på en konstant string, vilket också gör att den kan användas i en växel.
static bool Is123(ReadOnlySpan<char> s)
{
    return s is "123";
}
static bool IsABC(Span<char> s)
{
    return s switch { "ABC" => true, _ => false };
}
Detaljerad design
Vi ändrar specifikationen för konstanta mönster enligt följande (det föreslagna tillägget visas i fetstil):
Givet ett mönsterindatavärde
eoch ett konstant mönsterPmed konverterat värdev,
- om e har en integrerad typ eller uppräkningstyp, eller en nullbar form av en av dessa, och v har en integrerad typ, matchar mönstret
Pvärdet e om resultatet av uttryckete == värtrue; annars- Om e är av typen
System.Span<char>ellerSystem.ReadOnlySpan<char>och c är en konstant sträng och c inte har ett konstant värde pånullanses mönstret matcha omSystem.MemoryExtensions.SequenceEqual<char>(e, System.MemoryExtensions.AsSpan(c))returnerartrue.- mönstret
Pmatchar värdet e omobject.Equals(e, v)returnerartrue.
Välkända medlemmar
              System.Span<T> och System.ReadOnlySpan<T> matchas med namn, måste vara ref structs och kan definieras utanför corlib.
              System.MemoryExtensions matchas med namn och kan definieras utanför corlib.
Signaturen för System.MemoryExtensions.SequenceEqual-överlagringar måste matcha:
- public static bool SequenceEqual<T>(System.Span<T>, System.ReadOnlySpan<T>)
- public static bool SequenceEqual<T>(System.ReadOnlySpan<T>, System.ReadOnlySpan<T>)
Signaturen för System.MemoryExtensions.AsSpan måste matcha:
- public static System.ReadOnlySpan<char> AsSpan(string)
Metoder med valfria parametrar undantas från övervägande.
Nackdelar
Ingen
Alternativ
Ingen
Olösta frågor
- Ska matchning definieras oberoende av - MemoryExtensions.SequenceEqual()osv.- ... mönstret anses vara matchande om - e.Length == c.Lengthoch- e[i] == c[i]stämmer för alla tecken i- e.- Rekommendation: Definiera i termer av - MemoryExtensions.SequenceEqual()för prestanda. Om- MemoryExtensionssaknas, rapportera kompileringsfel.
- Bör matchning mot - (string)nulltillåtas?- I så fall, bör - (string)nullomfatta- ""eftersom- MemoryExtensions.AsSpan(null) == MemoryExtensions.AsSpan("")?- static bool IsEmpty(ReadOnlySpan<char> span) { return span switch { (string)null => true, // ok? "" => true, // error: unreachable? _ => false, }; }- Rekommendation: Konstant mönster - (string)nullska rapporteras som ett fel.
- Ska mönsterjämförelsen för konstanter innehålla ett typtest vid körning av uttrycksvärdet för - Span<char>eller- ReadOnlySpan<char>?- static bool Is123<T>(Span<T> s) { return s is "123"; // test for Span<char>? } static bool IsABC<T>(Span<T> s) { return s is Span<char> and "ABC"; // ok? } static bool IsEmptyString<T>(T t) where T : ref struct { return t is ""; // test for ReadOnlySpan<char>, Span<char>, string? }- Rekommendation: Inget implicit körningstyptest för konstant mönster. ( - IsABC<T>()exempel tillåts eftersom typtestet är explicit.)- Den här rekommendationen implementerades inte. Alla föregående exempel genererar ett kompilatorfel. 
- Ska subsumtion beakta konstanta strängmönster, listmönster och - Lengthegenskapsmönster?- static int ToNum(ReadOnlySpan<char> s) { return s switch { { Length: 0 } => 0, "" => 1, // error: unreachable? ['A',..] => 2, "ABC" => 3, // error: unreachable? _ => 4, }; }- Rekommendation: Samma undersumtionsbeteende som används när uttrycksvärdet är - string. (Innebär det ingen inkludering mellan konstanta strängar, listmönster och- Length, förutom att- [..]behandlas som ett som matchar vad som helst?)
Designa möten
C# feature specifications