You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When no dynamic expressions are involved, C# defaults to static binding, which means that the compile-time types of subexpressions are used in the selection process. However, when one of the subexpressions in the operations listed above is a dynamic expression, the operation is instead dynamically bound.
@@ -160,7 +160,7 @@ The precedence of an operator is established by the definition of its associated
If an operand of a *shift_expression* has the compile-time type `dynamic`, then the expression is dynamically bound ([§12.3.3](expressions.md#1233-dynamic-binding)). In this case, the compile-time type of the expression is `dynamic`, and the resolution described below will take place at run-time using the run-time type of those operands that have the compile-time type `dynamic`.
4511
4512
4512
-
For an operation of the form `x << count` or `x >> count`, binary operator overload resolution ([§12.4.5](expressions.md#1245-binary-operator-overload-resolution)) is applied to select a specific operator implementation. The operands are converted to the parameter types of the selected operator, and the type of the result is the return type of the operator.
4513
+
Dynamic binding uses values of type `enum System.Linq.Expressions.ExpressionType` to communicate binary operator kind to the runtime binder. As there is no enum member specifically representing an unsigned right shift operator, dynamic binding for `>>>` is not supported.
4514
+
4515
+
For an operation of the form `x << count`, `x >> count`, or `X >>> count`, binary operator overload resolution ([§12.4.5](expressions.md#1245-binary-operator-overload-resolution)) is applied to select a specific operator implementation. The left operand is converted to type `T`, where `T` is the first of `int`, `uint`, `long`, and `ulong` that can fully represent all possible values of the operand. The operation is then performed using the precision of type `T`, and the type of the result is `T`.
4513
4516
4514
4517
When declaring an overloaded shift operator, the type of the first operand shall always be the class or struct containing the operator declaration, and the type of the second operand shall always be `int`.
4515
4518
4519
+
The *unsigned_right_shift* operator (`>>>`) shall not be present in an expression tree.
4520
+
4521
+
> *Note*: The semantics of the predefined `>>>` operator on signed types cannot be accurately represented without adding conversions to an unsigned type and back. *end note*
4522
+
4516
4523
The predefined shift operators are listed below.
4517
4524
4518
4525
- Shift left:
@@ -4538,6 +4545,12 @@ The predefined shift operators are listed below.
4538
4545
nuintoperator>>(nuintx, intcount);
4539
4546
longoperator>>(longx, intcount);
4540
4547
ulongoperator>>(ulongx, intcount);
4548
+
intoperator>>>(intx, intcount);
4549
+
uintoperator>>>(uintx, intcount);
4550
+
nintoperator>>>(nintx, intcount);
4551
+
nuintoperator>>>(nuintx, intcount);
4552
+
longoperator>>>(longx, intcount);
4553
+
ulongoperator>>>(ulongx, intcount);
4541
4554
```
4542
4555
4543
4556
The `>>` operator shifts `x` right by a number of bits computed as described below.
@@ -4546,6 +4559,8 @@ The predefined shift operators are listed below.
4546
4559
4547
4560
When `x` is of type `uint`, `nuint`, or `ulong`, the low-order bits of `x` are discarded, the remaining bits are shifted right, and the high-order empty bit positions are set to zero.
4548
4561
4562
+
The `>>>` operator shifts `x` right by a number of bits computed as follows: The low-order bits of `x` are discarded, the remaining bits are shifted right, and the high-order empty bit positions are set to zero.
4563
+
4549
4564
For the predefined operators, the number of bits to shift is computed as follows:
4550
4565
4551
4566
- When the type of `x` is `int` or `uint`, the shift count is given by the low-order five bits of `count`. In other words, the shift count is computed from `count & 0x1F`. This also applies when the type of `x` is `nint` or `nuint`, and those types have the same size and representation as `int` and `uint`, respectively.
@@ -7022,6 +7037,9 @@ assignment
7022
7037
| simple_assignment
7023
7038
| compound_assignment
7024
7039
| ref_assignment
7040
+
| right_shift_assignment
7041
+
| unsigned_right_shift_assignment
7042
+
: unary_expression assignment_operator expression
7025
7043
;
7026
7044
```
7027
7045
@@ -7501,7 +7519,7 @@ Only the following constructs are permitted in constant expressions:
7501
7519
-`checked` and `unchecked` expressions.
7502
7520
-`nameof` expressions.
7503
7521
- The predefined `+`, `-`, `!` (logical negation) and `~` unary operators.
- The `!` null-forgiving operator ([§12.8.9](expressions.md#1289-null-forgiving-expressions)).
7507
7525
-`sizeof` expressions, provided the unmanaged-type is one of the types specified in [§24.6.9](unsafe-code.md#2469-the-sizeof-operator) for which `sizeof` returns a constant value.
0 commit comments