Corrispondenza del modello Span<char>
in una stringa costante
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 .
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
e
e un pattern costanteP
con 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
P
corrisponde 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
P
corrisponde 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 struct
e 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.Length
ee[i] == c[i]
corrispondono per tutti i caratteri ine
.Raccomandazione: definire in termini di
MemoryExtensions.SequenceEqual()
per le prestazioni. SeMemoryExtensions
manca, segnalare l'errore di compilazione.Deve essere consentito il confronto con
(string)null
?In tal caso,
(string)null
dovrebbe 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)null
deve 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