-
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
[NotNullWhen(true)] doesn't match [MaybeNullWhen(false)]—bug? Which one is right? #38191
Comments
Tagging @jcouv |
How about using More generally, |
Is that the same as Attempt 2 in the issue description? Is it intended that the implementation will still give a safety warning when assigning 'null' to such an out parameter? |
Yes, nullable attributes currently only affect callers, not methods bodies. There is an issue tracking that (#36039) |
OK, so it sounds like the answer for @jnm2 is: for now, go with attempt 2, and use |
@jcouv @RikkiGibson Thanks. Would you say that |
It is used in the effective signature of |
@RikkiGibson Right, but let's say I write a nongeneric public API with What's driving the signature is no longer anything intrinsic to the method. Now it's constrained by how it might be used. |
Right now the flow analysis attributes are just being completely ignored when we examine the method group -> delegate conversion. In a future release we may start examining the attributes when determining nullable convertibility for delegates, for OHI, etc. It will be difficult to give a definitive answer until then. It would probably be helpful to have folks upvote or comment on the linked issue #36039 in order to gauge the demand for this. |
'OHI' is a bit of jargon I haven't picked up on yet. I'll go ahead and leave a comment about the delegate conversion example in this thread. |
Thanks for pointing that out, I went ahead and expanded the acronym in that issue's description 😄 |
Awesome, thanks! Is it okay to leave this open until there is a definitive answer? |
Author's example is a bit long, so I decided to invest my 5 cents and write simple examples.
The problem is that analyzer does not pay attention on attributes. Only nullable value or not. So, for analyzer: I hope this helps someone. |
@jnm2 Looking up this thread, I believe the questions have been addressed. I'll go ahead and close as I'm cleaning up old nullability issues. FYI, I believe this issue is affected by a recent change (16.5p3) which enforces nullability attributes within method bodies. So that a method with a |
i think we should have clear guideline documented somewhere for below combinations |
I think these conventions are determined and implemented in the standard libraries over in https://github.com/dotnet/runtime, perhaps it would make sense to search for or raise an issue over there. |
@RikkiGibson thank you for help |
Version Used: VS 16.3 Preview 2
I don't know which is right,
[NotNullWhen(true)]
or[MaybeNullWhen(false)]
. Either way I have to use the!
operator to silence a warning.And isn't it a bug that they aren't considered equivalent?
See standalone repro below.
Setup
Given this NRT adaptation of real-world code:
Attempt 1:
[NotNullWhen(true)]
How should TryCombineStrings be annotated? It seemed
[NotNullWhen(true)] out string? combined
was the right thing to do because that's what I would do if it was a standalone method.But Roslyn says that it doesn't match
[MaybeNullWhen(false)] out string combined
even though it seems like they should be exactly equivalent:Attempt 2:
[MaybeNullWhen(false)]
Attempt 3: Generic instantiation with
string?
instead ofstring
This is all over the wrong thing to do. Null values should never be sent into
TryCombineStrings
and they should never come out ofCombiningAggregator
.In this demonstration, null strings are happening to not cause any warnings because the
.All
extension method andstring.Join
accept nulls. In the real-world project, there are a bunch of warnings because nothing was supposed to be nullable.Shouldn't attempt 1 just work? If not, why not? You'd never write attempt 2 if you were only calling the method directly, right?
Is the original, pre-C# 8 code flawed to begin with, and that's why I'm running into this problem?
The text was updated successfully, but these errors were encountered: