Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create user-defined-compound-assignment.md #9068

Merged
merged 22 commits into from
Jan 27, 2025
Merged
Changes from 1 commit
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
83467c1
Create user-defined-compound-assignment.md
AlekseyTs Jan 15, 2025
403387a
Update user-defined-compound-assignment.md
AlekseyTs Jan 15, 2025
299a5aa
Update user-defined-compound-assignment.md
AlekseyTs Jan 15, 2025
7e280b2
Update user-defined-compound-assignment.md
AlekseyTs Jan 15, 2025
1626182
Update user-defined-compound-assignment.md
AlekseyTs Jan 15, 2025
c4a0627
Update user-defined-compound-assignment.md
AlekseyTs Jan 15, 2025
e594409
Update user-defined-compound-assignment.md
AlekseyTs Jan 15, 2025
51743fe
Update user-defined-compound-assignment.md
AlekseyTs Jan 15, 2025
2551064
Update user-defined-compound-assignment.md
AlekseyTs Jan 15, 2025
a42d149
Update user-defined-compound-assignment.md
AlekseyTs Jan 16, 2025
51e7c9e
Update user-defined-compound-assignment.md
AlekseyTs Jan 16, 2025
fbf7ddc
Update user-defined-compound-assignment.md
AlekseyTs Jan 16, 2025
e9c6a46
Update user-defined-compound-assignment.md
AlekseyTs Jan 16, 2025
a20bef0
Update user-defined-compound-assignment.md
AlekseyTs Jan 16, 2025
8d4220d
Update user-defined-compound-assignment.md
AlekseyTs Jan 16, 2025
aeeb6f9
Update user-defined-compound-assignment.md
AlekseyTs Jan 16, 2025
0b93394
Update user-defined-compound-assignment.md
AlekseyTs Jan 17, 2025
b12331f
Update user-defined-compound-assignment.md
AlekseyTs Jan 17, 2025
5309948
Update user-defined-compound-assignment.md
AlekseyTs Jan 17, 2025
c2460dc
Update user-defined-compound-assignment.md
AlekseyTs Jan 21, 2025
7c9bfd1
Update user-defined-compound-assignment.md
AlekseyTs Jan 27, 2025
0f9d65c
Update user-defined-compound-assignment.md
AlekseyTs Jan 27, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Update user-defined-compound-assignment.md
AlekseyTs authored Jan 16, 2025
commit a20bef0ec33aaff39de9dd8077d399197304c4d4
72 changes: 69 additions & 3 deletions proposals/user-defined-compound-assignment.md
Original file line number Diff line number Diff line change
@@ -284,7 +284,73 @@ to allow the opeators to be void returning instance methods with a single parame

See https://github.com/dotnet/csharpstandard/blob/draft-v8/standard/expressions.md#1296-prefix-increment-and-decrement-operators

TODO:
The priority is given to [instance increment operators](#increment-operators) as follows.

First an attempt is made to process the operation by applying
[instance increment operator overload resolution](#instance-increment-operator-overload-resolution).
If the process produces no result and no error, then the operation is processed
by applying unary operator overload resolution as
https://github.com/dotnet/csharpstandard/blob/draft-v8/standard/expressions.md#1296-prefix-increment-and-decrement-operators
currently specifies.

Otherwise, an operation `«op»x` is evaluated as follows.

If type of `x` is known to be a reference type, the only requirement for `x` is that it must be an expression
classified as a value (i.e. it doesn't have to be classified as a variable, or be an access of a property with a set,
or be an access of an indexer with a set). The `x` is evaluated to get an instance `x₀`, the operator method is
invoked on that instance, and `x₀` is returned as result of the operation.
If `x₀` is `null`, the operator method invocation will throw a NullReferenceException.


For example:
``` C#
var a = ++(new C()); // var temp = new C(); temp.op_Increment(); a = temp;
var b = ++a; // a.op_Increment(); b = a;
++b; // b.op_Increment();
var d = ++C.P1; // var temp = C.get_P1(); temp.op_Increment(); d = temp;
var e = ++C.P2; // var temp = C.get_P2(); temp.op_Increment(); e = temp;
class C
{
public static C P1 { get; } = new C();
public static S P2 { get; set; } = new C();
AlekseyTs marked this conversation as resolved.
Show resolved Hide resolved

public static C operator ++(C x) => ...; // Never used by C#
public void operator ++() => ...;
}
```

If type of `x` is not known to be a reference type:
- If `x` is an expression classified as a variable,
- If result of increment is used, the `x` is evaluated to get an instance `x₀`, the operator method is
invoked on that instance, `x₀` is assigned to `x` and `x₀` is returned as result of
the compound assignment.
- Otherwise, the operator method is invoked on `x`.
- If it is a property access or indexer access, the property or indexer shall have both a get accessor
and a set accessor. If this is not the case, a binding-time error occurs. The property/indexer getter
is evaluated to get an instance `x₀`, the operator method is invoked on that instance,
the property/indexer setter is invoked with `x₀` as the value parameter, `x₀` is returned as result of the operation.

Note that side effects in `x` are evaluated only once in the process.

For example:
``` C#
var a = ++(new S()); // error: not a variable
var b = ++S.P2; // var temp = S.get_P2(); temp.op_Increment(); S.set_P2(temp); b = temp;
++b; // b.op_Increment();
var d = ++C.P1; // error: set is missing
var e = ++b; // var temp = b; temp.op_Increment(); e = (b = temp);
struct S
{
public static S P1 { get; } = new S();
public static S P2 { get; set; } = new S();

public static S operator ++(S x) => ...; // Never used by C#
public void operator ++() => ...;
}
```


### Postfix increment and decrement operators

@@ -358,7 +424,7 @@ var e = C.P2 += 12; // var temp = C.get_P2(); temp.op_AdditionAssignment(12); e
class C
{
public static C P1 { get; } = new C();
public static S P2 { get; set; } = new S();
public static S P2 { get; set; } = new C();

// op_Addition
public static C operator +(C x, int y) => ...;
@@ -379,7 +445,7 @@ If type of `x` is not known to be a reference type:
is evaluated to get an instance `x₀`, the operator method is invoked on that instance with `y` as the argument,
the property/indexer setter is invoked with `x₀` as the value parameter, `x₀` is returned as result of the compound assignment.

Note that `x` is evaluated only once in the process.
Note that side effects in `x` are evaluated only once in the process.

For example:
``` C#