Ослабление требований для оператора смены
Заметка
Эта статья является спецификацией компонентов. Спецификация служит проектным документом для функции. Она включает предлагаемые изменения спецификации, а также информацию, необходимую во время проектирования и разработки функции. Эти статьи публикуются до тех пор, пока предложенные изменения спецификации не будут завершены и включены в текущую спецификацию ECMA.
Может возникнуть некоторое несоответствие между спецификацией компонентов и завершенной реализацией. Эти различия фиксируются в соответствующих заметках совещаний по разработке языка (LDM).
Дополнительные сведения о процессе внедрения спецификаций функций в стандарт языка C# см. в статье о спецификациях .
Проблема чемпиона: https://github.com/dotnet/csharplang/issues/4666
Сводка
Требования к оператору смены будут расслаблены, чтобы правый операнд больше не был ограничен только int
.
Мотивация
При работе с типами, отличными от int
, нередко используется результат другого вычисления, например сдвиг на основе leading zero count
. Естественный тип чего-то подобного leading zero count
совпадает с типом входных данных (TSelf
) и поэтому во многих случаях это требует преобразования этого результата в int
перед сдвигом, даже если этот результат уже находится в пределах диапазона.
В контексте универсальных математических интерфейсов, которые библиотеки планируют предоставлять, это может быть проблематично, поскольку тип недостаточно известен, и поэтому преобразование в int
может быть невозможно или даже нечетко определено.
Подробный дизайн
Операторы сдвига
§12.11 следует изменить следующим образом:
- 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.
То есть остается ограничение, что первый операнд должен быть классом или структурой, содержащей объявление оператора.
Хотя ограничение на то, что второй операнд должен быть int
, удаляется.
Двоичные операторы
§14.10.3 следует изменить следующим образом:
-* 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.
То есть ограничение, что первым параметром должно быть T
или T?
, остается.
Ограничение, требующее, чтобы второй операнд был int
или int?
, было снято.
Разрешение перегрузки двоичных операторов
Первая точка маркера в §11.4.5 должна быть переформирована следующим образом:
- Определяется набор кандидатных пользовательских операторов, предоставляемых
X
иY
для операцииoperator op(x,y)
. Набор состоит из объединения операторов кандидатов, предоставляемыхX
и , если оператор не является оператором смены, операторы кандидатов, предоставляемыеY
, каждый определяется с помощью правил пользовательских операторов §11.4.6. ЕслиX
иY
одинакового типа илиX
иY
являются производными от общего базового типа, то общие кандидаты-операторы в объединённом наборе присутствуют только один раз.
То есть для операторов смены кандидаты являются только теми, которые предоставляются по типу X
.
Недостатки
Пользователи смогут определять операторы, которые не следуют рекомендациям, таким как реализация cout << "string"
в C#.
Альтернативы
Универсальные математические интерфейсы, предоставляемые библиотеками, могут предоставлять явно именованные методы. Это может сделать код более сложным для чтения и обслуживания.
Универсальные математические интерфейсы могут требовать смены int
и выполнения преобразования.
Это преобразование может быть дорогостоящим или невозможным в зависимости от рассматриваемого типа.
Неразрешенные вопросы
Существует ли озабоченность по поводу сохранения "намерения" вокруг того, почему второй операнд был ограничен int
?
Совещания по проектированию
https://github.com/dotnet/csharplang/blob/main/meetings/2022/LDM-2022-02-09.md
C# feature specifications