API Proposal: MemberNotNullWhenCompleteAttribute #5657
Replies: 7 comments 26 replies
-
Should there be a version of this attribute analogous to async Task<bool> TryFetchPotatoAsync() => ...;
if (await TryFetchPotatoAsync())
{
_potato.ToString(); // ok: _potato is not null
}
else
{
_potato.ToString(); // warning: _potato might be null
} |
Beta Was this translation helpful? Give feedback.
-
No response from MS on this? I just figured out why |
Beta Was this translation helpful? Give feedback.
-
The nullability improvements working group discussed this issue yesterday. |
Beta Was this translation helpful? Give feedback.
-
I use this "hack". But I don't like it, and I would be very happy if it got into the language, no matter how.
|
Beta Was this translation helpful? Give feedback.
-
I am surprised that the concept of "complete" for an async function call is "at first line of code that contains async", not "when the task is complete". If i used the Result property of an Task that is not completed (or look at any other side-effect of the execution), i'm in undefined behavior; of course prior to the await the _potato could be NULL - i wouldn't expect invariants of the function to be enforced while the Task is incomplete ...
not the pit of success, as I'd expect the same behavior as the blocking version...
|
Beta Was this translation helpful? Give feedback.
-
There's another variant of this problem, in a lazy-loaded scenario: Potato? _potato;
[MemberNotNull(nameof(_potato))]
public async Task FetchPotatoAsync()
{
if (_potato != null) return;
await Task.Delay(100); // WARNING: Member '_potato' must have a non-null value when exiting. [CS8774]
_potato = new Potato();
} In this particular case, I think the analyser should not complain because the object is already non-null. I added a feature request here. |
Beta Was this translation helpful? Give feedback.
-
I see there are a good number of 👍s on this discussion. I don't anticipate having time to continue design work on this in the short term. But, if someone wants to draft a proposal, including the specific public API changes, nullable analysis changes, and justification, based on the feedback from the below notes, I would be happy to review it. |
Beta Was this translation helpful? Give feedback.
-
Background and Motivation
MemberNotNullAttribute
indicate that when the method return, the given members are not null.This is perfect when your Initialisation code is fully synchronous.
But when using asynchronous code, the method may return on each await;
This means we can't use
MemberNotNullAttribute
to indicate that a member wont be null when an asynchronous operation completes.I believe this case is fairly common to justify either a change of behavior in
MemberNotNull
or a new attribute,MemberNotNullWhenCompleteAttribute
.Currently, if we ignore the warnings in
FetchPotatoAsync
, it will lead to the current behavior:Proposed API
This would be a verbatim copy of the
MemberNotNullAttribute
, except it guarantee the members wont be null when the returned value has been awaited/is completed.Usage Examples
Alternative Designs
The behavior of
MemberNotNullAttribute
can be altered:Stop emitting warning
Member '_potato' must have a non-null value when exiting.
on awaits, and thats it.It would be way more error prone to the user, but is way easier to implement.
Risks
I'm not aware of a risk.
Beta Was this translation helpful? Give feedback.
All reactions