-
Notifications
You must be signed in to change notification settings - Fork 4.1k
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
Null oblivious variables treated as non-null. #42318
Comments
I think this is by design. Null oblivious code is literally that - null oblivious. It should not warn if you dereference it, and you can assign null to it. If you assigned null to a null oblivious value, and then dereferenced it, it warns, because it's updated the state from null-oblivious to maybe null: x.Value = null; // No warning, correct.
x.Value.ToString(); // This warns But in your case, your first using the value, and then assigning null to it. |
@YairHalberstadt is correct. |
The question is if assuming the best is the right thing to do. I think assuming the worst makes more sense. There is absolutely no reason to assume the null oblivious API returns a non-null value, because returning null in null oblivious code is a perfectly correct and useful thing to do. Also, as a programmer I have absolutely no indication that the value I'm using is null oblivious. The compiler doesn't tell me, nor does Visual Studio. In fact, Visual Studio tells me the value is not null, even if I assign it to In short, this design choice is a great source for nasty null reference bugs, which is exactly what NRTs were supposed to prevent. If you have NRTs enabled, you don't ever expect the exception in my code snippet to be thrown, unless you willfully ignore warnings or use the null-forgiving operator. |
@qrjo Note there's an existing issue with plenty of discussion on this topic at dotnet/csharplang#2244 |
@qrjo The reasoning behind this decision is that a project doesn't control all the code it depends on. Referencing a null-oblivious library would yield lots of warnings, which would deter folks trying to migrate. There are many trade-offs involved in the nullability feature, and when in doubt we leaned towards less annoyance (the analysis is not the strictest it could be because we think that would be unbearable). That said, you are correct that null-oblivious are a potential source of danger. |
Well, all those errors are pretty easy to solve with the null-forgiving operator, right? The developer should be forced to think about whether to assign a value to a nullable variable or a non-nullable one. |
@qrjo We recognize that some folks want more strictness than the trade-off this feature was designed to provide. As @YairHalberstadt pointed out, this is good feedback and discussion to have on csharplang. |
"likely already safe" is a lot of assumption about code you have neither seen nor reviewed For reference, the google search that brought me here was "why am I not getting null warnings", and the reason I did that search is because I have a failing service that joyfully dereferences objects without null checks because the compiler would obviously warn me if those could have been null. Well they could, and were, and it didn't. |
@SRNissen as mentioned already, it's a tradeoff. We found that there were far too many false positives, making the feature unpalatable for the majority of users in the majority of user cases. So we went with a design that was actually viable, at the cost of potentially introducing false negatives. |
Version Used:
.NET Core 3.1, Visual Studio 16.4.5
Steps to Reproduce:
Calling nullable disabled code from nullable enabled code can cause missing warnings about NRTs. The code below demonstrates this. I can assign
null
toValue
without warning, yet I don't get warnings when I'm usingValue
as if it isn't nullable. When I hover overs
, Visual Studio wrongly tells me thats
is not null here. I can pass a null value toUseString
without getting warnings, which results in that method throwing the exception, becauses
should never be null there unless warnings were ignored.Changing
string s
tostring? s
has no effect. If I movex.Value = null;
above the assignment tos
, the warnings show up.Expected Behavior:
Warnings when using
Value
as a non-nullable string.Actual Behavior:
No warnings.
The text was updated successfully, but these errors were encountered: