From 28efe56136a24f8f78e8f919d9f48e34094fb82f Mon Sep 17 00:00:00 2001 From: AlekseyTs Date: Fri, 5 Nov 2021 06:40:36 -0700 Subject: [PATCH] Explicitly specify the order of evaluation for implicit Index/Range support (#5380) This is a follow up on an LDM decision, see https://github.com/dotnet/csharplang/blob/main/meetings/2021/LDM-2021-11-01.md for more information. --- proposals/csharp-8.0/ranges.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/proposals/csharp-8.0/ranges.md b/proposals/csharp-8.0/ranges.md index 60673fb..6750651 100644 --- a/proposals/csharp-8.0/ranges.md +++ b/proposals/csharp-8.0/ranges.md @@ -154,6 +154,12 @@ The new indexer will be implemented by converting the argument of type `Index` i - When the argument is of the form `^expr2` and the type of `expr2` is `int`, it will be translated to `receiver.Length - expr2`. - Otherwise, it will be translated as `expr.GetOffset(receiver.Length)`. +Regardless of the specific conversion strategy, the order of evaluation should be equivalent to the following: +1. `receiver` is evaluated; +2. `expr` is evaluated; +3. `length` is evaluated, if needed; +4. the `int` based indexer is invoked. + This allows for developers to use the `Index` feature on existing types without the need for modification. For example: ``` csharp @@ -221,7 +227,13 @@ This value will be re-used in the calculation of the second `Slice` argument. Wh - When `expr` is of the form `expr1..` (where `expr1` can be omitted), then it will be emitted as `receiver.Length - start`. - Otherwise, it will be emitted as `expr.End.GetOffset(receiver.Length) - start`. -The `receiver`, `Length`, and `expr` expressions will be spilled as appropriate to ensure any side effects are only executed once. For example: +Regardless of the specific conversion strategy, the order of evaluation should be equivalent to the following: +1. `receiver` is evaluated; +2. `expr` is evaluated; +3. `length` is evaluated, if needed; +4. the `Slice` method is invoked. + +The `receiver`, `expr`, and `length` expressions will be spilled as appropriate to ensure any side effects are only executed once. For example: ``` csharp class Collection {