Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Musterübereinstimmung
Anmerkung
Dieser Artikel ist eine Featurespezifikation. Die Spezifikation dient als Designdokument für das Feature. Es enthält vorgeschlagene Spezifikationsänderungen sowie Informationen, die während des Entwurfs und der Entwicklung des Features erforderlich sind. Diese Artikel werden veröffentlicht, bis die vorgeschlagenen Spezifikationsänderungen abgeschlossen und in die aktuelle ECMA-Spezifikation aufgenommen werden.
Es kann einige Abweichungen zwischen der Featurespezifikation und der abgeschlossenen Implementierung geben. Diese Unterschiede sind in den einschlägigen Notizen zum Sprachdesign-Meeting (LDM).
Weitere Informationen über den Prozess zur Aufnahme von Feature Speclets in den C#-Sprachstandard finden Sie in dem Artikel über die Spezifikationen.
Champion Issue: https://github.com/dotnet/csharplang/issues/8640
Zusammenfassung
Erlauben Sie den Mustervergleich einer Span<char> und eine ReadOnlySpan<char> auf eine konstante Zeichenkette.
Motivation
Für die Leistung, die Verwendung von Span<char> und ReadOnlySpan<char> wird in vielen Szenarien gegenüber String bevorzugt. Das Framework hat viele neue APIs hinzugefügt, mit denen Sie ReadOnlySpan<char> anstelle einer stringverwenden können.
Ein gängiger Vorgang für Zeichenfolgen besteht darin, einen Switch zu verwenden, um zu testen, ob es sich um einen bestimmten Wert handelt, und der Compiler optimiert einen solchen Schalter. Allerdings gibt es derzeit keine Möglichkeit, dasselbe auf einer ReadOnlySpan<char> effizienter zu gestalten, als den Wechsel und die Optimierung manuell durchzuführen.
Zur Förderung der Einführung von ReadOnlySpan<char> erlauben wir einen Mustervergleich ReadOnlySpan<char>, on a constant string, und kann somit auch in einem Schalter verwendet werden.
static bool Is123(ReadOnlySpan<char> s)
{
return s is "123";
}
static bool IsABC(Span<char> s)
{
return s switch { "ABC" => true, _ => false };
}
Detailliertes Design
Wir ändern die spec für konstante Muster wie folgt (der vorgeschlagene Zusatz ist fett gedruckt):
Angesichts eines Mustereingabewerts
eund ein konstantes MusterPmit umgerechnetem Wertv,
- wenn e einen Integral- oder Enum-Typ oder eine nullbare Form eines dieser Typen hat und v hat einen integralen Typ, das Muster
Ppasst zu der Wert e wenn das Ergebnis des Ausdruckse == vistrue; ansonsten- Wenn e vom Typ
System.Span<char>oderSystem.ReadOnlySpan<char>ist und c eine konstante Zeichenfolge ist und c keinen konstanten Wert vonnullaufweist, wird das Muster als übereinstimmend betrachtet, wennSystem.MemoryExtensions.SequenceEqual<char>(e, System.MemoryExtensions.AsSpan(c))truezurückgibt.- das Muster
Ppasst zu der Wert e wennobject.Equals(e, v)gibt zurücktrue.
Bekannte Mitglieder
System.Span<T> und System.ReadOnlySpan<T> mit dem Namen übereinstimmen, müssen ref structs, und kann außerhalb von corlib definiert werden.
System.MemoryExtensions wird nach Namen abgeglichen und kann außerhalb von corlib definiert werden.
Die Unterschrift von System.MemoryExtensions.SequenceEqual Überlastungen müssen übereinstimmen:
public static bool SequenceEqual<T>(System.Span<T>, System.ReadOnlySpan<T>)public static bool SequenceEqual<T>(System.ReadOnlySpan<T>, System.ReadOnlySpan<T>)
Die Unterschrift von System.MemoryExtensions.AsSpan müssen übereinstimmen:
public static System.ReadOnlySpan<char> AsSpan(string)
Methoden mit optionalen Parametern werden von der Berücksichtigung ausgeschlossen.
Nachteile
Nichts
Alternativen
Nichts
Ungelöste Fragen
Sollte die Übereinstimmung unabhängig von
MemoryExtensions.SequenceEqual()etc.?... wird das Muster als übereinstimmend angesehen, wenn
e.Length == c.Lengthunde[i] == c[i]für alle Zeichen ine.Empfehlung: Definieren Sie im Sinne von
MemoryExtensions.SequenceEqual()für Leistung. WennMemoryExtensionsfehlt, melden Sie den Kompilierungsfehler.Sollte der Abgleich mit
(string)nullerlaubt sein?Wenn ja, sollte
(string)nullfassen""seitMemoryExtensions.AsSpan(null) == MemoryExtensions.AsSpan("")?static bool IsEmpty(ReadOnlySpan<char> span) { return span switch { (string)null => true, // ok? "" => true, // error: unreachable? _ => false, }; }Empfehlung: Konstantes Muster
(string)nullsollte als Fehler gemeldet werden.Sollte die Konstantenmusterübereinstimmung einen Laufzeittyptest des Ausdruckswerts für
Span<char>orReadOnlySpan<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? }Empfehlung: Kein impliziter Laufzeittyptest für konstanten Muster. (
IsABC<T>()Beispiel ist erlaubt, weil der Typentest explizit ist).Diese Empfehlung wurde nicht implementiert. Alle vorherigen Beispiele erzeugen einen Compilerfehler.
Sollte die Subsumtion konstante Zeichenfolgenmuster, Listenmuster und
LengthEigenschaftsmuster?static int ToNum(ReadOnlySpan<char> s) { return s switch { { Length: 0 } => 0, "" => 1, // error: unreachable? ['A',..] => 2, "ABC" => 3, // error: unreachable? _ => 4, }; }Empfehlung: Gleiches Subsumtionsverhalten wie bei der Verwendung des Ausdruckswerts
string. (Bedeutet das, dass keine Subsumtion zwischen konstanten Zeichenketten, Listenmustern undLength, andere als die Behandlung[..]als übereinstimmend mit jeder?)
Entwurfsbesprechungen
C# feature specifications