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

Champion "conditional ref operator" (C# 7.2) #223

Open
gafter opened this issue Mar 3, 2017 · 17 comments
Open

Champion "conditional ref operator" (C# 7.2) #223

gafter opened this issue Mar 3, 2017 · 17 comments

Comments

@gafter
Copy link
Member

@gafter gafter commented Mar 3, 2017

See also

The idea would be to support a version of the ?: operator that yields an lvalue. The current proposal is to do so using ref after the : and ?, for example

   (array1 != null ? ref array1[index] : ref dummy) = value;
   ref Node next = ref (node != null) ? ref node.Next : ref head;
@VSadov
Copy link
Member

@VSadov VSadov commented Mar 3, 2017

@DavidArno - this was discussed:
Proposal: Add support for ternary ref expression

The proposal predates dotnet/csharplang, so it has not been moved to this repo yet.

@DavidArno
Copy link

@DavidArno DavidArno commented Mar 3, 2017

@VSadov,

Ah cool, thanks.

@VSadov
Copy link
Member

@VSadov VSadov commented Mar 3, 2017

There is also a PR with implementation. -
Implemented ref conditional operator (aka: ternary ref)

It is a relatively small feature. Basically a left over from the "ref returns".

@gafter
Copy link
Member Author

@gafter gafter commented Mar 3, 2017

@DavidArno This feature appeared in literally every example in the original feature request for ref locals and ref returns, but wasn't included in C# 7 along with the feature.

@lachbaer
Copy link
Contributor

@lachbaer lachbaer commented Mar 4, 2017

   (array1 == null ? ref array1[index] : ref dummy) = value;

Shouldn't it be array1 != null, or is my understanding of this feature wrong?
The reference to value cannot be stored in array1[index], if array1 doesn't exist...?!

@yaakov-h
Copy link
Contributor

@yaakov-h yaakov-h commented Mar 4, 2017

How about null-conditional expressions, e.g. ref array1?[index] ?? ref dummy? Would that be possible?

@gafter
Copy link
Member Author

@gafter gafter commented Mar 4, 2017

@yaakov-h I don't understand your proposal, but in any case it is certainly a different feature request than this one. If you're requesting a different feature please open a new issue for that.

@gafter gafter added this to the 7.2 candidate milestone Mar 6, 2017
@alrz
Copy link
Contributor

@alrz alrz commented Apr 19, 2017

Can we do this instead?

ref (array1 != null ? array1[index] : dummy) = value;
ref Node next = ref (node != null ? node.Next : head);
@VSadov
Copy link
Member

@VSadov VSadov commented Apr 20, 2017

@alrz - it would imply that (array1 != null ? array1[index] : dummy) is an LValue, which it is not.

That is easily observable if the expression returns a struct and you call a mutating method on it -
(array1 != null ? array1[index] : dummy).Mutate() - will not propagate mutations to the operands.

If the expression is supposed to be an LValue only as a part of ref assignment, then there is a need for more rules to figure when ternary is an LValue and when it is not, while being very careful with compat.
It gets more complicated when nested cases are considered.

And that is only to save typing one ref in a feature whose target audience often values explicitness.

@alrz
Copy link
Contributor

@alrz alrz commented Apr 20, 2017

I'm proposing that ref make it an lvalue if all branches are lvalue, same applies to other branching expressions as well,

ref (e1 ?? e2)
ref (e match { case P1: e1; case P2: e2; default: e3; })
ref (e1 ? e2 : e3)

Repeating ref on every branch AND the whole construct just seems redundant, IMHO.

@gafter gafter changed the title Champion "conditional ref operator" Champion "conditional ref operator" (C# 7.2) Sep 23, 2017
@yaakov-h
Copy link
Contributor

@yaakov-h yaakov-h commented Feb 15, 2018

It’s here now: https://github.com/dotnet/csharplang/blob/master/proposals/csharp-7.2/conditional-ref.md

It should probably be moved and re-tagged since it’s missed the 7.2 release.

@VSadov
Copy link
Member

@VSadov VSadov commented Feb 15, 2018

The feature is a part of 7.2
It was subsumed by the overall readonly ref theme which encompases multiple features related to the refs including conditional ref.

The up-to date description is a part of:
https://github.com/dotnet/csharplang/blob/master/proposals/csharp-7.2/readonly-ref.md

@yaakov-h
Copy link
Contributor

@yaakov-h yaakov-h commented Feb 16, 2018

Ah.

Should this be closed as a duplicate, then? 😁

@ojb500
Copy link

@ojb500 ojb500 commented Jun 15, 2018

It seems that this does not play nicely with throw-expressions.
In particular, the requirement that 'ref' follows both the ? and the : means that expressions like this are not legal

public ref T this[int index] => index == 0 ? ref _thing : throw new IndexOutOfRangeException();

This isn't super critical but it does save typing compared to an explicit if (index == 0) throw ....

Apologies if this is not the right place to post this.

@svick
Copy link
Collaborator

@svick svick commented Jun 15, 2018

@ojb500 There's already a separate issue about that: #919.

@ojb500
Copy link

@ojb500 ojb500 commented Jun 15, 2018

@svick - somehow did not find that when searching, thanks for the response.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
You can’t perform that action at this time.