Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Corrispondenza del modello
Nota
Questo articolo è una specifica di funzionalità. La specifica funge da documento di progettazione per la funzionalità. Include le modifiche specifiche proposte, insieme alle informazioni necessarie durante la progettazione e lo sviluppo della funzionalità. Questi articoli vengono pubblicati fino a quando le modifiche specifiche proposte non vengono completate e incorporate nella specifica ECMA corrente.
Potrebbero verificarsi alcune discrepanze tra la specifica di funzionalità e l'implementazione completata. Tali differenze vengono acquisite nelle note
Altre informazioni sul processo per l'adozione dei speclet delle funzionalità nello standard del linguaggio C# sono disponibili nell'articolo relativo alle specifiche .
Problema del "Champion": https://github.com/dotnet/csharplang/issues/8640
Sommario
Consenti la corrispondenza di pattern tra Span<char> e ReadOnlySpan<char> su una stringa costante.
Motivazione
Per la performance, l'utilizzo di Span<char> e ReadOnlySpan<char> è preferibile rispetto alle stringhe in molti scenari. Il framework ha aggiunto molte nuove API per consentire di usare ReadOnlySpan<char> al posto di un string.
Un'operazione comune sulle stringhe consiste nell'usare un'opzione per verificare se si tratta di un valore specifico e il compilatore ottimizza tale opzione. Tuttavia, attualmente non è possibile eseguire la stessa operazione su un ReadOnlySpan<char> in modo efficiente, ad eccezione dell'implementazione del commutatore e dell'ottimizzazione manualmente.
Per incoraggiare l'adozione di ReadOnlySpan<char> è possibile che i criteri corrispondano a un ReadOnlySpan<char>, in una costante string, consentendo così l'uso in un commutatore.
static bool Is123(ReadOnlySpan<char> s)
{
return s is "123";
}
static bool IsABC(Span<char> s)
{
return s switch { "ABC" => true, _ => false };
}
Progettazione dettagliata
La specifica di per i modelli costanti viene modificata nel modo seguente (l'aggiunta proposta è illustrata in grassetto):
Dato un valore di input del pattern
ee un pattern costantePcon valore convertitov,
- se e ha un tipo integrale o un tipo enumerazione oppure una forma nullable di uno di questi e v ha un tipo integrale, il criterio
Pcorrisponde il valore e se il risultato dell'espressionee == vètrue; altrimenti- Se e è di tipo
System.Span<char>oSystem.ReadOnlySpan<char>e c è una stringa costante e c non ha un valore costante dinull, il criterio viene considerato corrispondente seSystem.MemoryExtensions.SequenceEqual<char>(e, System.MemoryExtensions.AsSpan(c))restituiscetrue.- il criterio
Pcorrisponde il valore e seobject.Equals(e, v)restituiscetrue.
Membri noti
System.Span<T> e System.ReadOnlySpan<T> corrispondono in base al nome, devono essere di tipo ref structe possono essere definiti all'esterno di corlib.
System.MemoryExtensions corrisponde al nome e può essere definito all'esterno di corlib.
La firma degli overload di System.MemoryExtensions.SequenceEqual deve corrispondere:
public static bool SequenceEqual<T>(System.Span<T>, System.ReadOnlySpan<T>)public static bool SequenceEqual<T>(System.ReadOnlySpan<T>, System.ReadOnlySpan<T>)
La firma di System.MemoryExtensions.AsSpan deve corrispondere a:
public static System.ReadOnlySpan<char> AsSpan(string)
I metodi con parametri facoltativi vengono esclusi dalla considerazione.
Svantaggi
Nessuno
Alternative
Nessuno
Domande non risolte
La corrispondenza deve essere definita in modo indipendente da
MemoryExtensions.SequenceEqual()e così via?... il pattern viene considerato corrispondente se
e.Length == c.Lengthee[i] == c[i]corrispondono per tutti i caratteri ine.Raccomandazione: definire in termini di
MemoryExtensions.SequenceEqual()per le prestazioni. SeMemoryExtensionsmanca, segnalare l'errore di compilazione.Deve essere consentito il confronto con
(string)null?In tal caso,
(string)nulldovrebbe sottosumere""poichéMemoryExtensions.AsSpan(null) == MemoryExtensions.AsSpan("")?static bool IsEmpty(ReadOnlySpan<char> span) { return span switch { (string)null => true, // ok? "" => true, // error: unreachable? _ => false, }; }raccomandazione: il modello costante
(string)nulldeve essere segnalato come errore.La corrispondenza con il pattern costante deve includere un test del tipo di runtime del valore dell'espressione su
Span<char>oReadOnlySpan<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? }Raccomandazione: nessun test implicito del tipo di runtime per il modello costante. (
IsABC<T>()esempio è consentito perché il test del tipo è esplicito.Questa raccomandazione non è stata implementata. Tutti gli esempi precedenti generano un errore del compilatore.
La subsommazione deve considerare modelli di stringa costanti, modelli di elenco e modelli di proprietà di
Length?static int ToNum(ReadOnlySpan<char> s) { return s switch { { Length: 0 } => 0, "" => 1, // error: unreachable? ['A',..] => 2, "ABC" => 3, // error: unreachable? _ => 4, }; }Raccomandazione: lo stesso comportamento di sottosumpazione usato quando il valore dell'espressione è
string. (Ciò significa che non esiste alcuna inclusione tra stringhe costanti, modelli di elenco eLength, tranne nel caso in cui[..]sia considerato corrispondente a qualsiasi?)
Riunioni di progettazione
C# feature specifications