Skip to content

Commit 31ad881

Browse files
RexJaeschkeBillWagner
authored andcommitted
fix formatting
1 parent 82c2e6b commit 31ad881

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
@@ -1867,15 +1867,15 @@ If the *primary_no_array_creation_expression* of an *element_access* is a value
18671867
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.
18681868

18691869
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*.
1870-
1870+
18711871
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.
18721872

18731873
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:
18741874

18751875
- `P` is evaluated. If this evaluation causes an exception, no further steps are executed.
18761876
- 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`.
18771877

1878-
- For an index expression not having type `System.Range`:
1878+
- For an index expression not having type `System.Range`:
18791879
- 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.
18801880
- 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.
18811881
- 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.
@@ -1886,55 +1886,69 @@ The run-time processing of an array access of the form `P[A]`, where `P` is a *p
18861886
- The result of the transformation becomes the result of the array access.
18871887

18881888
> *Example*: Given the following one-dimensional array and Index:
1889+
>
18891890
> ```csharp
18901891
> string[] words = new string[] { "red", "green", "blue" };
18911892
> Index idx = 1;
18921893
> ```
1894+
>
18931895
> `words[idx]` is transformed by the implementation to
1896+
>
18941897
> ```csharp
18951898
> words[idx.GetOffset(words.Length)]
18961899
> ```
1900+
>
18971901
> 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*
18981902
18991903
> *Example*: Given the following jagged array and Indexes:
1904+
>
19001905
> ```csharp
19011906
> int[][] values = new int[][] { … };
19021907
> Index idx1 = 1;
19031908
> Index idx2 = ^1;
19041909
> ```
1905-
> ` values[idx1][idx2]` is transformed by the implementation to
1910+
>
1911+
> `values[idx1][idx2]` is transformed by the implementation to
19061912
> ```csharp
19071913
> values[idx1.GetOffset(values.Length)][idx2.GetOffset(values[idx1].Length)]
19081914
> ```
19091915
> *end example*
19101916
19111917
> *Example*: Given the following multidimensional array and Indexes:
1918+
>
19121919
> ```csharp
19131920
> int[,] values2D = { … };
19141921
> Index idx3 = 1;
19151922
> Index idx4 = ^1;
19161923
> ```
1924+
>
19171925
> 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
1926+
>
19181927
> ```csharp
19191928
> values2D[idx3.GetOffset(values2D.GetUpperBound(0) + 1), idx4.GetOffset(values2D.GetUpperBound(1) + 1)]
19201929
> ```
1930+
>
19211931
> *end example*
19221932
19231933
> *Example*: Given the following one-dimensional array:
19241934
> ```csharp
19251935
> string[] seasons = new string[] { "Summer", "Autumn", "Winter", "Spring" };
19261936
> ```
19271937
> `seasons[0..2]` is transformed by the implementation to
1938+
>
19281939
> ```csharp
19291940
> System.Runtime.CompilerServices.RuntimeHelpers.GetSubArray<string>(seasons, 0..2)
19301941
> ```
1942+
>
19311943
> which returns the `string[]` slice containing `"Summer"` and `"Autumn"`. *end example*
19321944
19331945
> *Example*: Given the following jagged array:
1946+
>
19341947
> ```csharp
19351948
> int[][] values = new int[][] { new int[] { 10, 9, 5 },
19361949
> new int[] { 6, 12, 17, 32 }, new int[] { 28, 42 } };
19371950
> ```
1951+
>
19381952
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*
19391953
19401954
#### 11.7.10.3 Indexer access
@@ -1954,9 +1968,7 @@ The binding-time processing of an indexer access of the form `P[A]`, where `P` i
19541968
19551969
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.18.2](expressions.md#11182-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)).
19561970
1957-
> *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*
1958-
1959-
> *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*
1971+
> *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*
19601972
19611973
### 11.7.11 Null Conditional Element Access
19621974
@@ -3098,6 +3110,44 @@ The result of evaluating `~x`, where `X` is an expression of an enumeration ty
30983110

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

3113+
### §index-from-end-operator Index-from-end operator
3114+
3115+
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.
3116+
3117+
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:
3118+
3119+
```csharp
3120+
System.Index operator ^(int fromEnd);
3121+
```
3122+
3123+
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)`.
3124+
3125+
If after implicit conversion to `int` the operand has a negative value, an exception of type `System.ArgumentOutOfRangeException` is thrown.
3126+
3127+
Lifted ([§11.4.8](expressions.md#1148-lifted-operators)) forms of the unlifted predefined index-from-end operator defined above are also predefined.
3128+
3129+
> *Example*: The following example uses array and string indexable sequences:
3130+
>
3131+
> ```csharp
3132+
> string[] words = new string[] { "red", "green", "blue" };
3133+
> words[^1] // OK: "blue"
3134+
> words[^3] // OK: "red"
3135+
> words[^0] // refers to the (non-existent) element beyond the end
3136+
>
3137+
> Index idx = ^0; // OK; no attempt made to access any non-existent element
3138+
> int i = -1;
3139+
> idx = ^(ushort)i; // OK; 65535 (0x0000FFFF) from the end
3140+
> idx = ^(short)i; // System.ArgumentOutOfRangeException:
3141+
>
3142+
> string s = "Hello!";
3143+
> int? iN = 5;
3144+
> Index? idx4 = ^iN; // OK: non-null, ^5
3145+
> s[^idx4.Value.Value] // OK: "e"
3146+
> ```
3147+
>
3148+
> `^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`.)
3149+
> *end example*
3150+
31013151
### 11.8.6 Prefix increment and decrement operators
31023152
31033153
```ANTLR
@@ -3230,6 +3280,55 @@ At run-time, the expression `await t` is evaluated as follows:
32303280

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

3283+
<<<<<<< HEAD
3284+
=======
3285+
## §range-operator Range operator
3286+
3287+
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).
3288+
3289+
```ANTLR
3290+
range_expression
3291+
: unary_expression
3292+
| range_expression? '..' range_expression?
3293+
;
3294+
```
3295+
3296+
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:
3297+
3298+
```csharp
3299+
System.Range operator ..(System.Index start = 0, System.Index end = ^0);
3300+
```
3301+
3302+
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,
3303+
3304+
- `s .. e` is transformed by the implementation to `new System.Range(s, e)`.
3305+
- `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);`).
3306+
- `.. 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);`).
3307+
- `..` 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; }`).
3308+
3309+
> *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*
3310+
3311+
Lifted ([§11.4.8](expressions.md#1148-lifted-operators)) forms of the unlifted predefined range operator defined above are also predefined.
3312+
3313+
> *Example*: The following example uses array and string indexable sequences:
3314+
>
3315+
> ```csharp
3316+
> string[] seasons = new string[] { "Summer", "Autumn", "Winter", "Spring" };
3317+
> seasons[1..3] // string[2] "Autumn", "Winter"
3318+
> seasons[^2..^1] // string[1] "Winter"
3319+
> seasons[2..] // string[2] "Winter", "Spring"
3320+
> seasons[1..1] // string[0]
3321+
>
3322+
> string s2 = "Hello!";
3323+
> Index? startN = 1;
3324+
> Index? endN = ^2;
3325+
> Range? r = startN .. endN;
3326+
> s2[r.Value] // OK: "ell"
3327+
> ```
3328+
>
3329+
> *end example*
3330+
3331+
>>>>>>> 76616f9 (fix formatting)
32333332
## 11.9 Arithmetic operators
32343333
32353334
### 11.9.1 General

0 commit comments

Comments
 (0)