{"action":"created","issue":{"url":"https://api.github.com/repos/dotnet/roslyn/issues/5961","labels_url":"https://api.github.com/repos/dotnet/roslyn/issues/5961/labels{/name}","comments_url":"https://api.github.com/repos/dotnet/roslyn/issues/5961/comments","events_url":"https://api.github.com/repos/dotnet/roslyn/issues/5961/events","html_url":"https://github.com/dotnet/roslyn/issues/5961","id":111437631,"number":5961,"title":"Proposal: Poisonous Null-checking","user":{"login":"alrz","id":3105979,"avatar_url":"https://avatars.githubusercontent.com/u/3105979?v=3","gravatar_id":"","url":"https://api.github.com/users/alrz","html_url":"https://github.com/alrz","followers_url":"https://api.github.com/users/alrz/followers","following_url":"https://api.github.com/users/alrz/following{/other_user}","gists_url":"https://api.github.com/users/alrz/gists{/gist_id}","starred_url":"https://api.github.com/users/alrz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/alrz/subscriptions","organizations_url":"https://api.github.com/users/alrz/orgs","repos_url":"https://api.github.com/users/alrz/repos","events_url":"https://api.github.com/users/alrz/events{/privacy}","received_events_url":"https://api.github.com/users/alrz/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/dotnet/roslyn/labels/Area-Language%20Design","name":"Area-Language Design","color":"5319e7"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":28,"created_at":"2015-10-14T16:33:02Z","updated_at":"2015-10-15T22:01:16Z","closed_at":null,"body":"With a lot of null-checking features introduced in C# language up to this version (and more on the way), there is some cases that still need for null-checking (assuming that it is a valid value so it's not addressed by #5032).\r\n\r\nFor example `value` in `F(value);` can be `null `but `F` can't be called with a `null` (in case of a non-nullable reference type), or shouldn't (throwing exceptions). So you need to check for `null` before calling it like\r\n```cs\r\nif(value != null) F(value);\r\n```\r\nIn cases like this, there should be a feature in which you check for a `null` on an *expression* and if it's a `null` make it a poison value for the rest of the expression. e.g.\r\n```cs\r\nF(value?);\r\n```\r\nso `F` wouldn't be called if `value` is `null`.\r\n\r\n*EDIT:* There could be a `checked`-like keyword to control the null-checking context for the expression or statement. I don't know what else would be a good choice for this but `check` seems concise and meaningful. Although, I insist to exclude this and use some rules to determine the scope of the target expression.\r\n\r\nIf `F` is not a `void`-returning function, then the whole expression would be `default(T)`.\r\n```cs\r\nobject result = F(value?) ?? defaultValue;\r\n// instead of\r\nobject result = value != null ? F(value) : defaultValue;\r\n\r\nbool result = foo.Bar != baz?;\r\n// instead of\r\nbool result = baz != null && foo.Bar != baz;\r\n\r\nbool result = F(Foo.Bar?.Baz?);\r\n// instead of\r\nbool result = Foo.Bar?.Baz != null && F(Foo.Bar.Baz);\r\n```\r\nYou can see how this would be useful."},"comment":{"url":"https://api.github.com/repos/dotnet/roslyn/issues/comments/148535467","html_url":"https://github.com/dotnet/roslyn/issues/5961#issuecomment-148535467","issue_url":"https://api.github.com/repos/dotnet/roslyn/issues/5961","id":148535467,"user":{"login":"HaloFour","id":10102290,"avatar_url":"https://avatars.githubusercontent.com/u/10102290?v=3","gravatar_id":"","url":"https://api.github.com/users/HaloFour","html_url":"https://github.com/HaloFour","followers_url":"https://api.github.com/users/HaloFour/followers","following_url":"https://api.github.com/users/HaloFour/following{/other_user}","gists_url":"https://api.github.com/users/HaloFour/gists{/gist_id}","starred_url":"https://api.github.com/users/HaloFour/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/HaloFour/subscriptions","organizations_url":"https://api.github.com/users/HaloFour/orgs","repos_url":"https://api.github.com/users/HaloFour/repos","events_url":"https://api.github.com/users/HaloFour/events{/privacy}","received_events_url":"https://api.github.com/users/HaloFour/received_events","type":"User","site_admin":false},"created_at":"2015-10-15T22:01:16Z","updated_at":"2015-10-15T22:01:16Z","body":"Except that null propagation propagates `Nullable<T>` in place of an expression that would result in `T`, so `default(T)` doesn't apply and doesn't make sense.  It also is not designed to propagate up to parent nodes of the expression, only to children.  It's right-associative for a reason (which was not the initial design, btw).  The discussion as to the reason for the null propagation operator in C# is still available across quite a few posts on CodePlex.  As mentioned, this operator exists in this form in other languages, it wasn't invented by the C# team."}}