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

Proposal: Allow Null-conditional operators to be lvalues #1106

Closed
jcouv opened this issue Nov 14, 2017 · 17 comments
Closed

Proposal: Allow Null-conditional operators to be lvalues #1106

jcouv opened this issue Nov 14, 2017 · 17 comments

Comments

@jcouv
Copy link
Member

jcouv commented Nov 14, 2017

@SetTrend commented on Wed Sep 21 2016

Currently you cannot assign a value to an object's property if that property may be null.

I suggest to allow for the Null-conditional operator to become an lvalue.

This would allow for the following statement to compile without error:

System.Web.HttpContext.Current?.Response.StatusCode = 200;

Everything right to a runtime null value is suggested not to be executed/evaluated.

So at run-time, the following two statements would be equivalent, given that any of the Null-conditional operator yielded null:

// GetCounterAndIncrement() is not getting called if myObject or NullableProperty yields null
myObject?.NullableProperty?.intProperty = GetCounterAndIncrement();

// equivalent
if (myObject != null && myObject.NullableProperty != null)
  myObject.NullableProperty.intProperty = GetCounterAndIncrement();

... same for function calls:

// GetCounterAndIncrement() is not getting called if myObject or NullableProperty yields null
GetMyObject()?.NullableProperty?.intProperty = GetCounterAndIncrement();

// equivalent
if ((var temp = GetMyObject()) != null && temp.NullableProperty != null)
  temp.NullableProperty.intProperty = GetCounterAndIncrement();

RFC


@alrz commented on Wed Sep 21 2016

Related: dotnet/roslyn#1276


@hardhub commented on Wed Nov 08 2017

myObject?.NullableProperty.intProperty = GetCounterAndIncrement();

It looks strange... Should you get null reference exception if myObject is null?


@alrz commented on Wed Nov 08 2017

I think we could translate the assignment operator of the form:

var result = (expression?.Member = value);

to a ternary of the form:

var temp = expression;
var result = (temp != null ? (temp.Member = value) : fallbackValue);
  • If type of the assignment expression is nullable, fallbackValue is emitted as default(T) where T is the type of that expression.
  • If type of the assignment expression is non-nullable, fallbackValue is emitted as default(T?) where T is the type of that expression.

Similarly, we may use -= and += (event subscription and unsubscription) operators with a conditional access on the left-hand-side (#1276), but in that case, the resultant type of the whole expression is void just like var x = obj?.Event += handler; // ERROR as you can't assign void.

This could be extended to conditional indexer access or other compound assignments too.


@SetTrend commented on Thu Nov 09 2017

@hardhub: 👍 😳

Oops ... Edited my original posting to show expected behaviour. Thanks for pointing it out!


@CyrusNajmabadi commented on Fri Nov 10 2017

  1. As a language proposal, this should probably go to csharplang. Paging @jcouv as he's good at moving these.
  2. A big part of ?. is not executing code once null is hit. i.e. if i have:

x?.Foo(a1, b1, c1) then a1, b1, c1 are not evaluated if x is null. It seems strange that in x?.y = z that z would be evaluated if it's not going to be assigned into anything.


@jcouv commented on Tue Nov 14 2017

Moving to csharplang

@jnm2
Copy link
Contributor

jnm2 commented Nov 14, 2017

Related: #737

@ghost
Copy link

ghost commented Feb 26, 2018

@gafter

@reinspi, you know you are no longer welcome in this repo. Please stay away and do not post comments.

I cannot agree with that. Even if I also do not think that suggested solution is better than one proposed in issue we cannot stop considering alternative opinions.

Matters do not stand so well with mankind that the majority should prefer the better course: the more people do a thing the worse it is likely to be. Let us therefore inquire, not what is most commonly done, but what is best for us to do.

Lucius Annaeus Seneca

@ghost
Copy link

ghost commented Feb 26, 2018

@Inzanit you are the victim of social networks.
I would prefer to hear what you think, rather than see how you hide behind the screen of smiles.

Or maybe what I said is very close to you?
After all, what is “Like”, if not the approval of the majority?

@jnm2
Copy link
Contributor

jnm2 commented Feb 26, 2018

@hardhub I'm glad you missed it—this person was banned for incessant rudeness. This is the (third?) time he's tried to circumvent the ban. @gafter is right that he is not welcome here.

@TAGC
Copy link

TAGC commented Feb 26, 2018

@jnm2 Pretty sure hardhub is one of Makeloft's alts lol.

@jnm2
Copy link
Contributor

jnm2 commented Feb 26, 2018

@TAGC I've seen hardhub around long before Makeloft, so I doubt it.

@ghost
Copy link

ghost commented Feb 26, 2018

I'm glad you missed it—this person was banned for incessant rudeness.

@jnm2 Maybe, I do not know. But I do not see anything except criticism in his post. I personally do not like technical idea of @reinspi. And think his solution cannot be named elegant. But I am ready for discussions. At least it is what he suggested "constructive discussions and arguments."
I do not know how he meets above ideas. But that sounds much pretty than what @gafter said.

So I appreciate any criticism independently of rudeness or vulnerability of any person of community.
If it is some sort of Linus-style then it is absolutely acceptable for me.
And hey guys I am also community :)

TAGC you are idiot (or blindman... although it is not the topic).
But your post shows very well how community can be wrong.
And it is just the question which I tried to show here.

@jnm2
Copy link
Contributor

jnm2 commented Feb 26, 2018

@hardhub Calling someone an idiot, besides being gratuitous, violates the dotnet org's code of conduct.

@masonwheeler
Copy link

@hardhub It's not just his technical ideas. He's a sockpuppet of someone who's been banned on here for bad conduct, and doing that is unacceptable pretty much everywhere.

@tannergooding
Copy link
Member

@hardhub, please refrain from "personal attacks". As @jnm2 mentioned, this violates the code of conduct (specifically the "Be respectful" section) we have for this repository (and all repositories under dotnet).

@ghost
Copy link

ghost commented Feb 26, 2018

@hardhub Calling someone an idiot, besides being gratuitous, violates the dotnet org's code of conduct.

First, I do not think it is gratuitous:
It is necessary to be very mindless to assume that I am related to the original author.
And all that only because I say that you are too subjective in your attacks on him.

Second, we are on GitHub man.. and it is open-source community!
I personally do not have any respect to Microsoft code of conduct.
I have own understanding what is acceptable and what is not.
I do not think for example that TAGC post is not "personal attack".

It's not just his technical ideas.

I am about only his posts in current issue (I did not see any other his posts).
In that post he wrote the following:
System.Web.HttpContext.Current?.Response.StatusCode = 200;
may be successfully rewritten and compiled with C# 7
System.Web.HttpContext.Current.To(out var c)?.With(c.Response.StatusCode = 200);
See: An extended 'with' pattern implementation into C#

It is obviously only technical description of some not very good idea.
Also he wrote: I am surprised at your emotional reaction instead of constructive discussions and arguments.
Considering only such posts I can say his position looks much better than "hey man go away" from public community.

I do not like to discuss it further:

  1. I think my first message is an enough good signal to understand that your majority can make mistakes (at least in how you are communicating with minority members).
  2. If it is not enough signal for majority then it especially does not make sense to participate in further discussions.

Just assumption... maybe this community is too weak because it has too much MS employees...?

So all what I wanted to say, I said, please, do not misinterpret my words, and on that let's finish this discussion.

@masonwheeler
Copy link

I personally do not have any respect to Microsoft code of conduct.
I have own understanding what is acceptable and what is not.

And that's fine. But this community has its own understanding as well, and those who can't hold to it don't belong here. They can take their personal understanding elsewhere.

@dotnet dotnet locked as off-topic and limited conversation to collaborators Feb 26, 2018
@tannergooding
Copy link
Member

tannergooding commented Feb 26, 2018

I have temporarily locked this thread as it is quickly becoming off-topic.

CC. @richlander, @jaredpar, @gafter, @terrajobst, @jongalloway

@terrajobst
Copy link
Member

terrajobst commented Feb 26, 2018

Considering tone & style I concluded that hardhub is another version of makeloft, I added him to the list of blocked users. Sigh.

It would help our case if we collectively decided not to engage with this user any further. Arguing has shown not to work; it's just wasting time everyone's time and makes already challenging threads even harder to read. We're working with GitHub support to find a better way to deal with this but meanwhile ignoring that user, deleting any comments, and banning the user account is the way to go IMHO.

So everyone: please stop feeding the troll.

@dotnet dotnet unlocked this conversation Apr 7, 2018
@dusho
Copy link

dusho commented Apr 18, 2018

would really like this feature more than other things that are getting in C#
to have

SelectedUnit.GetComponentController<MovementComponentController>()?.MoveFinishedHandler -= SelectedUnitFinishedMoving;

instead of

if (SelectedUnit.GetComponentController<MovementComponentController>() != null)
                SelectedUnit.GetComponentController<MovementComponentController>().MoveFinishedHandler -= SelectedUnitFinishedMoving;

or

var moveComp = SelectedUnit.GetComponentController<MovementComponentController>();
                if (moveComp != null)
                {
                    moveComp.MoveFinishedHandler = SelectedUnitFinishedMoving;
                }

@ahdung
Copy link

ahdung commented Nov 1, 2018

+1

@MadsTorgersen MadsTorgersen reopened this Sep 8, 2020
@svick
Copy link
Contributor

svick commented Aug 14, 2021

This is a duplicate of #2883 and since that issue is championed, I'm going to close this issue.

@svick svick closed this as completed Aug 14, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Tracking: Julien
Awaiting triage
Development

No branches or pull requests

12 participants