Compartir vía


Relajación de los requisitos de los operadores de desplazamiento

Nota

Este artículo es una especificación de características. La especificación actúa como documento de diseño de la característica. Incluye cambios de especificación propuestos, junto con la información necesaria durante el diseño y el desarrollo de la característica. Estos artículos se publican hasta que se finalizan los cambios de especificación propuestos e se incorporan en la especificación ECMA actual.

Puede haber algunas discrepancias entre la especificación de características y la implementación completada. Esas diferencias se recogen en las notas de la reunión de diseño de lenguaje (LDM) correspondientes.

Puede obtener más información sobre el proceso de adopción de especificaciones de características en el estándar del lenguaje C# en el artículo sobre las especificaciones de .

Resumen

Los requisitos del operador de desplazamiento se relajarán para que el operando derecho ya no esté restringido a ser únicamente int.

Motivación

Cuando se trabaja con tipos distintos de int, no es infrecuente que se desplace utilizando el resultado de otro cálculo, como el desplazamiento basado en el leading zero count. El tipo natural de algo como un leading zero count es el mismo que el tipo de entrada (TSelf) y, por lo tanto, en muchos casos, esto requiere convertir ese resultado en int antes de cambiar, incluso si ese resultado ya está dentro del intervalo.

En el contexto de las interfaces matemáticas genéricas que las bibliotecas planean exponer, esto es potencialmente problemático, ya que el tipo no es bien conocido y, por lo tanto, la conversión a int puede no ser posible o incluso estar bien definida.

Diseño detallado

Operadores de desplazamiento

§12.11 debe volver a escribirse de la siguiente manera:

- 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.

Es decir, la restricción de que el primer operando sea la clase o estructura que contiene la declaración del operador permanece. Se elimina la restricción de que el segundo operando debe ser int.

Operadores binarios

§14.10.3 debe volver a escribirse de la siguiente manera:

-*  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.

Es decir, la restricción de que el primer parámetro sea T o T? permanece. Aunque se quita la restricción de que el segundo operando debe ser int o int?.

Resolución de la sobrecarga del operador binario

El primer punto en §11.4.5 debe ser reformulado de la siguiente manera:

  • Se determina el conjunto de operadores candidatos definidos por el usuario proporcionados por X y Y para la operación operator op(x,y). El conjunto consiste en la unión de los operadores candidatos proporcionados por X y , a menos que el operador sea un operador de desplazamiento, los operadores candidatos proporcionados por Y, cada uno determinado utilizando las reglas de Operadores candidatos definidos por el usuario §11.4.6. Si X y Y son del mismo tipo, o si X y Y se derivan de un tipo base común, los operadores candidatos compartidos solo se producen en el conjunto combinado una vez.

Es decir, para los operadores de desplazamiento, los operadores candidatos son solo los proporcionados por el tipo X.

Inconvenientes

Los usuarios podrán definir operadores que no sigan las directrices recomendadas, como implementar cout << "string" en C#.

Alternativas

En su lugar, las interfaces matemáticas genéricas expuestas por las bibliotecas podrían exponer métodos con nombre explícito. Esto puede dificultar la lectura y mantenimiento del código.

Las interfaces matemáticas genéricas podrían requerir la toma de turno int y que se realice una conversión. Esta conversión puede ser costosa o puede no ser posible en función del tipo en cuestión.

Preguntas sin resolver

¿Hay preocupación por conservar la "intención" alrededor de por qué el segundo operando estaba restringido a int?

Reuniones de diseño

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