I am working in a project with nullable annotation context enabled, but we have a dependency on a library with nullable annotation context disabled.
Simplified example of the static analysis behavior I'm seeing in our project:
class Something
{
static void Main(string[] args)
{
Foo foo = new();
Console.WriteLine("foo.Bar: " + foo.Bar); // Null static analysis claim: 'Bar' is not null here. Runtime behavior: 'Bar' is null
}
}
#nullable disable
class Foo
{
public string Bar { get; set; }
}
My question is: is this static analysis behavior expected? It would be great to be able to rely on the null static analysis features to reason about our code & omit unnecessary null checks, but this is giving me doubts.
Yes, this is by design. When you have a code compiled with NRT disabled you will get nullable-oblivious state. From Nullable contexts section of the docs:
The nullable annotation context determines the compiler's behavior. There are four values for the nullable annotation context:
disable
: The code is nullable-oblivious. Disable matches the behavior before nullable reference types were enabled, except the new syntax produces warnings instead of errors.
From the Nullable reference types (NRTs) docs:
Reference type variables in code compiled in a disabled context are nullable-oblivious. ... However, the default state of a nullable-oblivious variable is not-null.
And from Understand contexts and warnings:
Each variable has a default nullable state that depends on its nullability:
- Nullable variables have a default
null-state
ofmaybe-null
.- Non-nullable variables have a default
null-state
ofnot-null
.- Nullable oblivious variables have a default
null-state
ofnot-null
.