Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Patroonovereenkomst
Notitie
Dit artikel is een functiespecificatie. De specificatie fungeert als het ontwerpdocument voor de functie. Het bevat voorgestelde specificatiewijzigingen, samen met informatie die nodig is tijdens het ontwerp en de ontwikkeling van de functie. Deze artikelen worden gepubliceerd totdat de voorgestelde specificaties zijn voltooid en opgenomen in de huidige ECMA-specificatie.
Er kunnen enkele verschillen zijn tussen de functiespecificatie en de voltooide implementatie. Deze verschillen worden vastgelegd in de relevante LDM (Language Design Meeting) notities.
Meer informatie over het proces voor het aannemen van functiespeclets in de C#-taalstandaard vindt u in het artikel over de specificaties.
Kampioenprobleem: https://github.com/dotnet/csharplang/issues/8640
Samenvatting
Sta patroonmatching toe van een Span<char> en een ReadOnlySpan<char> op een constante string.
Motivatie
Voor performance heeft het gebruik van Span<char> en ReadOnlySpan<char> de voorkeur boven strings in veel scenario's. Het framework heeft veel nieuwe API's toegevoegd waarmee u ReadOnlySpan<char> kunt gebruiken in plaats van een string.
Een veelvoorkomende bewerking voor tekenreeksen is het gebruik van een switch-instructie om te testen of het een bepaalde waarde is, waarbij de compiler zo'n switch optimaliseert. Er is momenteel echter geen manier om hetzelfde te doen op een ReadOnlySpan<char> efficiënt, behalve het handmatig implementeren van de switch en de optimalisatie.
Om de acceptatie van ReadOnlySpan<char> te bevorderen, staan we toe dat een patroon dat overeenkomt met een ReadOnlySpan<char>, op een constante stringwordt gebruikt, zodat het ook in een switch kan worden toegepast.
static bool Is123(ReadOnlySpan<char> s)
{
    return s is "123";
}
static bool IsABC(Span<char> s)
{
    return s switch { "ABC" => true, _ => false };
}
Gedetailleerd ontwerp
We wijzigen de specificatie voor constante patronen als volgt (de voorgestelde toevoeging wordt vet weergegeven):
Gezien een patrooninvoerwaarde
een een constant patroonPmet geconverteerde waardev,
- als e integraal type of opsommingstype heeft, of een null-vorm van een van deze, en v integraal type heeft, komt het patroon
 Povereen met de waarde e als het resultaat van de expressiee == vtrueis; anders- Als e van het type
 System.Span<char>ofSystem.ReadOnlySpan<char>is en c een constante tekenreeks is en c- geen constante waarde vannullheeft, wordt het patroon beschouwd als overeenkomend alsSystem.MemoryExtensions.SequenceEqual<char>(e, System.MemoryExtensions.AsSpan(c))trueretourneert.- Het patroon
 Pkomt overeen met de waarde e wanneerobject.Equals(e, v)trueretourneert.
Bekende leden
              System.Span<T> en System.ReadOnlySpan<T> overeenkomen met de naam, moeten ref structzijn en kunnen buiten corlib worden gedefinieerd.
              System.MemoryExtensions wordt op naam vergeleken en kan buiten corlib worden gedefinieerd.
De signatuur van System.MemoryExtensions.SequenceEqual overloads moet overeenkomen:
public static bool SequenceEqual<T>(System.Span<T>, System.ReadOnlySpan<T>)public static bool SequenceEqual<T>(System.ReadOnlySpan<T>, System.ReadOnlySpan<T>)
De handtekening van System.MemoryExtensions.AsSpan moet overeenkomen met:
public static System.ReadOnlySpan<char> AsSpan(string)
Methoden met optionele parameters worden uitgesloten van overweging.
Nadelen
Geen
Alternatieven
Geen
Niet-opgeloste vragen
Moeten overeenkomsten onafhankelijk van
MemoryExtensions.SequenceEqual()enzovoort worden gedefinieerd?... het patroon wordt beschouwd als overeenkomend als
e.Length == c.Lengthene[i] == c[i]voor alle tekens ine.Aanbeveling: definieer in termen van
MemoryExtensions.SequenceEqual()voor de prestaties. AlsMemoryExtensionsontbreekt, rapporteert u een compilatiefout.Moet matchen tegen
(string)nulltoegestaan worden?Als dat het geval is, moet
(string)null""insluiten sindsMemoryExtensions.AsSpan(null) == MemoryExtensions.AsSpan("")?static bool IsEmpty(ReadOnlySpan<char> span) { return span switch { (string)null => true, // ok? "" => true, // error: unreachable? _ => false, }; }Aanbeveling: Het constantenpatroon
(string)nullmoet als een fout worden gerapporteerd.Moet de constante patroonmatching een runtime-typetest bevatten van de expressiewaarde voor
Span<char>ofReadOnlySpan<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? }Aanbeveling: Geen impliciete runtimetypetest voor constant patroon. (
IsABC<T>()voorbeeld is toegestaan omdat de typetest expliciet is.)Deze aanbeveling is niet geïmplementeerd. Alle voorgaande voorbeelden produceren een compilerfout.
Moet subsumptie rekening houden met constante tekenreekspatronen, lijstpatronen en
Length-eigenschapspatronen?static int ToNum(ReadOnlySpan<char> s) { return s switch { { Length: 0 } => 0, "" => 1, // error: unreachable? ['A',..] => 2, "ABC" => 3, // error: unreachable? _ => 4, }; }Aanbeveling: Hetzelfde subsumeringsgedrag dat wordt gebruikt wanneer de expressiewaarde
stringis. (Betekent dit geen subsamenvatting tussen constante tekenreeksen, lijstpatronen enLength, behalve het behandelen van[..]als overeenkomende waarden?)
Ontwerpvergaderingen
C# feature specifications