Condividi tramite


Allentamento dei requisiti dell'operatore di spostamento

Nota

Questo articolo è una specifica delle 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 language design meeting (LDM) pertinenti.

Altre informazioni sul processo di adozione delle speclet di funzionalità nel linguaggio C# sono disponibili nell'articolo dedicato alle specifiche .

Problema del campione: https://github.com/dotnet/csharplang/issues/4666

Sommario

I requisiti dell'operatore di spostamento saranno flessibili in modo che l'operando sul lato destro non sia più limitato solo a essere int.

Motivazione

Quando si usano tipi diversi da int, non è insolito effettuare uno spostamento utilizzando il risultato di un altro calcolo, ad esempio basandosi su leading zero count. Il tipo naturale di qualcosa come un leading zero count è lo stesso del tipo di input (TSelf), quindi, in molti casi, ciò richiede di convertire tale risultato in int prima di eseguire lo spostamento, anche se quel risultato è già all'interno dell'intervallo.

Nel contesto delle interfacce matematiche generiche che le librerie stanno pianificando di esporre, questo è potenzialmente problematico poiché il tipo non è ben noto e quindi la conversione in int potrebbe non essere possibile né neanche ben definita.

Progettazione dettagliata

Operatori di spostamento

§12.11 deve essere riformulato nel modo seguente:

- When declaring an overloaded shift operator, the type of the first operand must always be the class or struct containing the operator declaration,
and the type of the second operand must always be int.
+ When declaring an overloaded shift operator, the type of the first operand must always be the class or struct containing the operator declaration.

Ovvero, la restrizione che il primo operando sia la classe o lo struct che contiene la dichiarazione dell'operatore rimane. La restrizione che imponeva il secondo operando dovesse essere int è stata rimossa.

Operatori binari

il di 14.10.3 deve essere riformulato nel modo seguente:

-*  A binary `<<` or `>>` operator must take two parameters, the first of which must have type `T` or `T?` and the second of which must have type `int` or `int?`, and can return any type.
+*  A binary `<<` or `>>` operator must take two parameters, the first of which must have type `T` or `T?`, and can return any type.

Ovvero, la restrizione che il primo parametro deve essere T o T? rimane. La restrizione secondo cui il secondo operando deve essere int o int? è stata rimossa.

Risoluzione dell'overload dell'operatore binario

Il primo punto puntato a §11.4.5 deve essere riformulato come segue:

  • Viene determinato il set di operatori definiti dall'utente candidati forniti da X e Y per l'operazione operator op(x,y). Il set è costituito dall'unione degli operatori candidati forniti da X e , a meno che l'operatore non sia un operatore shift, gli operatori candidati forniti da Y, ognuno determinato utilizzando le regole degli operatori definiti dall'utente candidati §11.4.6. Se X e Y sono dello stesso tipo o se X e Y derivano da un tipo di base comune, gli operatori candidati condivisi si verificano solo una volta nel set combinato.

Per gli operatori di spostamento, gli unici operatori candidati sono quelli forniti dal tipo X.

Svantaggi

Gli utenti potranno definire gli operatori che non seguono le linee guida consigliate, ad esempio l'implementazione di cout << "string" in C#.

Alternative

Le interfacce matematiche generiche offerte dalle librerie potrebbero esporre metodi denominati in modo esplicito. Ciò può rendere il codice più difficile da leggere/gestire.

Le interfacce matematiche generiche potrebbero richiedere l'esecuzione del turno int e l'esecuzione di una conversione. Questa conversione può essere costosa o potrebbe non essere possibile a seconda del tipo in questione.

Domande non risolte

C'è preoccupazione per mantenere l'"intento" del motivo per cui il secondo operando è stato limitato a int?

Riunioni di design

https://github.com/dotnet/csharplang/blob/main/meetings/2022/LDM-2022-02-09.md