Skip to content

Commit 86a7ea8

Browse files
RexJaeschkeBillWagner
authored andcommitted
fix formatting
1 parent 09171a9 commit 86a7ea8

File tree

1 file changed

+105
-6
lines changed

1 file changed

+105
-6
lines changed

standard/expressions.md

Lines changed: 105 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1899,15 +1899,15 @@ If the *primary_no_array_creation_expression* of an *element_access* is a value
18991899
For an array access, the *primary_no_array_creation_expression* of the *element_access* shall be a value of an *array_type*. Furthermore, the *argument_list* of an array access shall not contain named arguments. The number of expressions in the *argument_list* shall be the same as the rank of the *array_type*, and each expression shall be of type `int`, `uint`, `long`, `ulong`, `System.Index`, or `System.Range`, or shall be implicitly convertible to one or more of the types `int`, `uint`, `long`, or `ulong`. However, it is a compile-time error for an *argument_list* expression of type `System.Index` or `System.Range` to be used for any dimension of a multi-dimensional array.
19001900

19011901
The result of evaluating an array access that does not involve `System.Range` is a variable of the element type of the array, namely the array element selected by the value(s) of the expression(s) in the *argument_list*.
1902-
1902+
19031903
The result of evaluating an array access that involves `System.Range` is a slice of the array being accessed, as selected by the value(s) of the expression(s) in the *argument_list*. The resulting slice’s element type is the same as the element type of the array being accessed.
19041904

19051905
The run-time processing of an array access of the form `P[A]`, where `P` is a *primary_no_array_creation_expression* of an *array_type* and `A` is an *argument_list*, consists of the following steps:
19061906

19071907
- `P` is evaluated. If this evaluation causes an exception, no further steps are executed.
19081908
- The index expressions of the *argument_list* are evaluated in order, from left to right. Following evaluation of each index expression, for expressions not having type `System.Index` or `System.Range`, an implicit conversion ([§10.2](conversions.md#102-implicit-conversions)) to one of the following types is performed: `int`, `uint`, `long`, `ulong`. The first type in this list for which an implicit conversion exists is chosen. For instance, if the index expression is of type `short` then an implicit conversion to `int` is performed, since implicit conversions from `short` to `int` and from `short` to `long` are possible. For an index expression having type `System.Index`, the Index is transformed into the corresponding `int` index using `System.Index.GetOffset`.
19091909

1910-
- For an index expression not having type `System.Range`:
1910+
- For an index expression not having type `System.Range`:
19111911
- If evaluation of an index expression, the subsequent implicit conversion, or Index transformation causes an exception, then no further index expressions are evaluated, and no further steps are executed.
19121912
- The value of `P` is checked to be valid. If the value of `P` is `null`, a `System.NullReferenceException` is thrown and no further steps are executed.
19131913
- The value of each expression in the *argument_list* is checked against the actual bounds of each dimension of the array instance referenced by `P`. If one or more values are out of range, a `System.IndexOutOfRangeException` is thrown and no further steps are executed.
@@ -1918,55 +1918,69 @@ The run-time processing of an array access of the form `P[A]`, where `P` is a *p
19181918
- The result of the transformation becomes the result of the array access.
19191919

19201920
> *Example*: Given the following one-dimensional array and Index:
1921+
>
19211922
> ```csharp
19221923
> string[] words = new string[] { "red", "green", "blue" };
19231924
> Index idx = 1;
19241925
> ```
1926+
>
19251927
> `words[idx]` is transformed by the implementation to
1928+
>
19261929
> ```csharp
19271930
> words[idx.GetOffset(words.Length)]
19281931
> ```
1932+
>
19291933
> which results in `"green"`. Similarly, `words[^0]` is transformed by the implementation to `words[(^0).GetOffset(words.Length)]`, which results in `System.IndexOutOfRangeException`. *end example*
19301934
19311935
> *Example*: Given the following jagged array and Indexes:
1936+
>
19321937
> ```csharp
19331938
> int[][] values = new int[][] { … };
19341939
> Index idx1 = 1;
19351940
> Index idx2 = ^1;
19361941
> ```
1937-
> ` values[idx1][idx2]` is transformed by the implementation to
1942+
>
1943+
> `values[idx1][idx2]` is transformed by the implementation to
19381944
> ```csharp
19391945
> values[idx1.GetOffset(values.Length)][idx2.GetOffset(values[idx1].Length)]
19401946
> ```
19411947
> *end example*
19421948
19431949
> *Example*: Given the following multidimensional array and Indexes:
1950+
>
19441951
> ```csharp
19451952
> int[,] values2D = { … };
19461953
> Index idx3 = 1;
19471954
> Index idx4 = ^1;
19481955
> ```
1956+
>
19491957
> as `Index`-typed subscripts are not supported in this context, what one might like to express simply as `values2D[idx3, idx4]` must instead be rewritten explicitly by the programmer as
1958+
>
19501959
> ```csharp
19511960
> values2D[idx3.GetOffset(values2D.GetUpperBound(0) + 1), idx4.GetOffset(values2D.GetUpperBound(1) + 1)]
19521961
> ```
1962+
>
19531963
> *end example*
19541964
19551965
> *Example*: Given the following one-dimensional array:
19561966
> ```csharp
19571967
> string[] seasons = new string[] { "Summer", "Autumn", "Winter", "Spring" };
19581968
> ```
19591969
> `seasons[0..2]` is transformed by the implementation to
1970+
>
19601971
> ```csharp
19611972
> System.Runtime.CompilerServices.RuntimeHelpers.GetSubArray<string>(seasons, 0..2)
19621973
> ```
1974+
>
19631975
> which returns the `string[]` slice containing `"Summer"` and `"Autumn"`. *end example*
19641976
19651977
> *Example*: Given the following jagged array:
1978+
>
19661979
> ```csharp
19671980
> int[][] values = new int[][] { new int[] { 10, 9, 5 },
19681981
> new int[] { 6, 12, 17, 32 }, new int[] { 28, 42 } };
19691982
> ```
1983+
>
19701984
all the Range and Index expressions in `values[1..3][^1][..2][^1]` are transformed by the implementation, resulting in `values[2][1]`, which is 42. *end example*
19711985
19721986
#### 11.7.10.3 Indexer access
@@ -1986,9 +2000,7 @@ The binding-time processing of an indexer access of the form `P[A]`, where `P` i
19862000
19872001
Depending on the context in which it is used, an indexer access causes invocation of either the *get_accessor* or the *set_accessor* of the indexer. If the indexer access is the target of an assignment, the *set_accessor* is invoked to assign a new value ([§11.19.2](expressions.md#11192-simple-assignment)). In all other cases, the *get_accessor* is invoked to obtain the current value ([§11.2.2](expressions.md#1122-values-of-expressions)).
19882002
1989-
> *Note*: An implementation is required to provide an instance indexer member with a single parameter of type `Index` for any type that meets the criteria specified in §indexable-sequence-impl-support-for-index. *end note*
1990-
1991-
> *Note*: An implementation is required to provide an instance indexer member with a single parameter of type `Range` for any type that meets the criteria specified in §indexable-sequence-impl-support-for-range. *end note*
2003+
> *Note*: An implementation is required to provide an instance indexer member with a single parameter of type `Index` for any type that meets the criteria specified in §indexable-sequence-impl-support-for-index. An implementation is required to provide an instance indexer member with a single parameter of type `Range` for any type that meets the criteria specified in §indexable-sequence-impl-support-for-range. *end note*
19922004
19932005
### 11.7.11 Null Conditional Element Access
19942006
@@ -3174,6 +3186,44 @@ The result of evaluating `~x`, where `X` is an expression of an enumeration ty
31743186

31753187
Lifted ([§11.4.8](expressions.md#1148-lifted-operators)) forms of the unlifted predefined bitwise complement operators defined above are also predefined.
31763188

3189+
### §index-from-end-operator Index-from-end operator
3190+
3191+
This operator provides a succinct syntax for denoting the position of an element in an indexable sequence (§indexable-sequence) relative to the end of that sequence.
3192+
3193+
For an operation of the form `^x`, unary operator overload resolution ([§11.4.4](expressions.md#1144-unary-operator-overload-resolution)) is applied to select a specific operator implementation. The operand is converted to the parameter type of the selected operator, and the type of the result is the return type of the operator. Only one predefined index-from-end operator exists:
3194+
3195+
```csharp
3196+
System.Index operator ^(int fromEnd);
3197+
```
3198+
3199+
For this operator, an object of (the immutable struct) type `System.Index` is returned that denotes element number `fromEnd` from the end of any indexable sequence. `^n` is shorthand for `new System.Index(n, fromEnd: true)`.
3200+
3201+
If after implicit conversion to `int` the operand has a negative value, an exception of type `System.ArgumentOutOfRangeException` is thrown.
3202+
3203+
Lifted ([§11.4.8](expressions.md#1148-lifted-operators)) forms of the unlifted predefined index-from-end operator defined above are also predefined.
3204+
3205+
> *Example*: The following example uses array and string indexable sequences:
3206+
>
3207+
> ```csharp
3208+
> string[] words = new string[] { "red", "green", "blue" };
3209+
> words[^1] // OK: "blue"
3210+
> words[^3] // OK: "red"
3211+
> words[^0] // refers to the (non-existent) element beyond the end
3212+
>
3213+
> Index idx = ^0; // OK; no attempt made to access any non-existent element
3214+
> int i = -1;
3215+
> idx = ^(ushort)i; // OK; 65535 (0x0000FFFF) from the end
3216+
> idx = ^(short)i; // System.ArgumentOutOfRangeException:
3217+
>
3218+
> string s = "Hello!";
3219+
> int? iN = 5;
3220+
> Index? idx4 = ^iN; // OK: non-null, ^5
3221+
> s[^idx4.Value.Value] // OK: "e"
3222+
> ```
3223+
>
3224+
> `^idx4.Value.Value` is the `int` position from the end of the sequence designated by the `Index` wrapped in the `Index?` designated by `idx4`. (`System.Nullable<T>`and `System.Index` both have public read-only properties called `Value`.)
3225+
> *end example*
3226+
31773227
### 11.8.6 Prefix increment and decrement operators
31783228
31793229
```ANTLR
@@ -3306,6 +3356,55 @@ At run-time, the expression `await t` is evaluated as follows:
33063356

33073357
An awaiter’s implementation of the interface methods `INotifyCompletion.OnCompleted` and `ICriticalNotifyCompletion.UnsafeOnCompleted` should cause the delegate `r` to be invoked at most once. Otherwise, the behavior of the enclosing async function is undefined.
33083358

3359+
<<<<<<< HEAD
3360+
=======
3361+
## §range-operator Range operator
3362+
3363+
This operator provides a succinct syntax for specifying a (possibly empty) element range suitable for use in denoting a slice of an indexable sequence (§indexable-sequence).
3364+
3365+
```ANTLR
3366+
range_expression
3367+
: unary_expression
3368+
| range_expression? '..' range_expression?
3369+
;
3370+
```
3371+
3372+
For an operation of the form `s .. e`, binary operator overload resolution ([§11.4.5](expressions.md#1145-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. Only one predefined range operator exists:
3373+
3374+
```csharp
3375+
System.Range operator ..(System.Index start = 0, System.Index end = ^0);
3376+
```
3377+
3378+
The left and right operands denote, respectively, a start and end Index. For this operator, an object of (the immutable struct) type `System.Range` is returned that contains those Indexes. If the left operand is omitted, an Index of `0` is used. If the right operand is omitted, an Index of `^0` is used. As such,
3379+
3380+
- `s .. e` is transformed by the implementation to `new System.Range(s, e)`.
3381+
- `s ..` is transformed by the implementation to `new System.Range(s, ^0)` (or to `System.Range.StartAt(s)` if that method exists, is accessible, and is declared as follows: `public static Range StartAt (Index start);`).
3382+
- `.. e` is transformed by the implementation to `new System.Range(0, e)` (or to `System.Range.EndAt(e)` if that method exists, is accessible, and is declared as follows: `public static Range EndAt (Index end);`).
3383+
- `..` is transformed by the implementation to `new System.Range(0, ^0)` (or instead to `System.Range.All` if that property exists, is accessible, and is declared as follows: `public static Range All { get; }`).
3384+
3385+
> *Note*: While a Range can be created with a start Index greater than the end Index, any attempt to use that Range to denote a slice from an indexable sequence will result in `System.ArgumentOutOfRangeException`. *end note*
3386+
3387+
Lifted ([§11.4.8](expressions.md#1148-lifted-operators)) forms of the unlifted predefined range operator defined above are also predefined.
3388+
3389+
> *Example*: The following example uses array and string indexable sequences:
3390+
>
3391+
> ```csharp
3392+
> string[] seasons = new string[] { "Summer", "Autumn", "Winter", "Spring" };
3393+
> seasons[1..3] // string[2] "Autumn", "Winter"
3394+
> seasons[^2..^1] // string[1] "Winter"
3395+
> seasons[2..] // string[2] "Winter", "Spring"
3396+
> seasons[1..1] // string[0]
3397+
>
3398+
> string s2 = "Hello!";
3399+
> Index? startN = 1;
3400+
> Index? endN = ^2;
3401+
> Range? r = startN .. endN;
3402+
> s2[r.Value] // OK: "ell"
3403+
> ```
3404+
>
3405+
> *end example*
3406+
3407+
>>>>>>> 76616f9 (fix formatting)
33093408
## 11.9 Arithmetic operators
33103409
33113410
### 11.9.1 General

0 commit comments

Comments
 (0)