-
Notifications
You must be signed in to change notification settings - Fork 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
Add attributes to indicate that a method result implies nullability of a member. #2997
Comments
As for the optional parameter on |
While I like the idea as I've run into a similar issue, in the case above you could end up with a race condition if another thread changes the |
The compiler is already lax in regards to property access race conditions. For example this code: if (x.Name != null)
{
x.Name = x.Name.ToUpper();
} doesn't produce a warning, even though theoretically the |
Note that |
If it's a property and not a field the value gets stored in a temporary first. I'd argue thats a bit different w/r/t race conditions. Sharplab |
If it's a reference type, it gets stored in a temporary too. My point was that |
I believe the reasoning behind being lax was that being strict would result in far too many false positives. I base that upon this Mads Torgersen's article (look under the "Avoiding dereferencing of nulls" section). I'd argue this proposal addresses the exact same case - decrease the number of false positives generated for users of your API in terms of NRTs. |
I believe that the discussion of multithreaded issues is tangential to this proposal. This proposal addreses the difference between #nullable enable
class Foo
{
public string? Name { get; set; }
public bool HasName => Name != null;
public void NameToUpperCase()
{
if (HasName)
{
Name = Name.ToUpper();
}
}
} And this: #nullable enable
class Foo
{
public string? Name { get; set; }
public void NameToUpperCase()
{
if (Name != null)
{
Name = Name.ToUpper();
}
}
} Both of these code samples have identical vulnerability to null dereference errors if they are accessed from multiple threads simultaneously. The first code segment gives a warning and the second does not. That is the distinction this proposal wishes to address. |
Why is this still not implemented in the language/framework? |
Duplicate of #3297. This is part of C# 9, the MemberNotNull and MemberNotNullWhen attributes. |
Please consider the following code:
On the Name=Name.ToUpper() I get a warning that Name is a possible null reference, which is clearly incorrect. I can cure this warning by inlining HasName so the condition is if (Name != null).
Inlining may be suboptimal for several reasons. HasName might actually test a lot more things, and I might want to use it in several places, or it might be a public part of the API surface. There are many reasons to want to factor the null check into it's own method, but doing so seems to break the nullable reference checker.
I propose the addition of an optional parameter to the NotNullWhen, MaybeNullWhen, and NotNulIIfNotNull attributes to give the name of a field or property on the containing class which should receive the not-null constraint. Thus the code above could be written
The C# compiler should then understand that the true return result from HasName implies that Name is not null and the code should compile without warnings.
I further propose an optional parameter on the NonNull attribute to indicate a field or property that is not null if the annotated member returns at all. This would allow the following code:
The text was updated successfully, but these errors were encountered: