Reputation: 20748
When working with .NET Standard 2.1 code, I found a strange behaviour when there should have been a warning to a nullable parameter but it does not:
And I can reproduce it with a simple method:
#nullable enable // making sure that nullability is enabled
static void Foo(IEnumerable<string>? a = default)
{
Console.WriteLine(a.Count());
string? b = null;
Console.WriteLine(b.Length);
}
With the above code compiled in netstandard2.1
, there is no warning for a
. Nullable context does work because there is CS8602
(dereference of a possibly null reference) for b
.
When switching to net8.0
for example, the compiler correctly raises CS8604
for a
. This is built using .NET 9 SDK.
What's going on here? Is it a bug in the compiler?
Upvotes: 1
Views: 69
Reputation: 273530
.NET standard does not have nullability annotations. It does not use the nullable reference types feature. It's as if you are using a library that has #nullable disable
.
For example, compare how the EqualityComparer<T>.Equals
method is declared. In .NET 9, it's
public abstract bool Equals (T? x, T? y);
In .NET Standard, it's
public abstract bool Equals (T x, T y);
The same goes for the the parameter of the Enumerable.Count
method - it's just that "not nullable" (in a #nullable enable
environment) is syntactically the same as "not annotated" (in a #nullable disable
environment), so there is no visual difference.
Therefore, the compiler is oblivious to what can and can't be null in all the .NET Standard APIs, and the compiler is designed to not raise warnings in such a situation. Otherwise (if the compiler assumes everything is nullable) you will likely get a lot of warnings when you try to use an old, unannotated library.
See also this GitHub issue, which says that it is not planned for .NET Standard to get nullable annotations in the future.
Upvotes: 2