3

I've looked but can't figure out why I am not getting an exception when I pass a null for a string parameter in a constructor when I have null reference types enabled.

Don't constructor parameters get treated as non-nullable?

Here's my constructor:

public ApiClient( string baseUrl, string authorizationToken ) {

    string testString = null;
    _apiClientBaseUrl = baseUrl ?? throw new ArgumentNullException( $"{nameof(baseUrl)} cannot be null" );
    _authorizationToken = authorizationToken ?? throw new ArgumentNullException( $"{nameof(authorizationToken)} cannot be null" );
}

I do get an error for the string testString = null; line. If I remove the coded null tests I can pass in nulls for the 2 properties and don't get any error. The object will instantiate just fine.

I am in a .NET Core 3.1 project with this in the .csproj file:

<PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <Nullable>enable</Nullable>
    <WarningsAsErrors>CS8600;CS8602;CS8603;CS8625</WarningsAsErrors>
    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
Peter Duniho
  • 68,759
  • 7
  • 102
  • 136
  • 6
    It doesn't work that way: https://learn.microsoft.com/en-us/dotnet/csharp/nullable-references - "These *warnings are emitted at compile time*. The compiler doesn't add any null checks or other runtime constructs in a nullable context. *At runtime, a nullable reference and a non-nullable reference are equivalent.*" Do ensure to include *actual* compiler errors (or warnings, which may be treated as errors). – user2864740 Oct 21 '20 at 20:52
  • 1
    See this post regarding ``, which might help you catch this compile-time. Note: still won't work right if you're referencing a DLL from another project, sadly... https://stackoverflow.com/questions/58194983/how-to-treat-all-c-sharp-8-nullable-reference-warnings-as-errors – CoolBots Oct 21 '20 at 20:59
  • Running this code, I get the expected error thrown when calling `new ApiClient(null, null)`. – Abion47 Oct 21 '20 at 21:00
  • 1
    @Abion47 you've missed the "If I remove the coded null tests I can pass in nulls for the 2 properties and don't get any error" part in OP's question. I did so originally too =) – Guru Stron Oct 21 '20 at 21:05
  • @ user2864740 - Thanks for the info, but I do get a compile time error for the "string testString = null;" line. The code won't compile with the "TreatWarningsAsErrors" option(s). I added these lines to that constructor: TestMethod( null ); TestMethod( testString ); TestMethod( baseUrl ); And this method: private void TestMethod( string testString ) { string x = testString; } I get red squgglies for the first 2 lines but not the third. – raaaaaaaandy Oct 22 '20 at 22:06

1 Answers1

7

Nullable reference types are used for compile time static analysis only, as the docs state:

Nullable reference types aren't new class types, but rather annotations on existing reference types. The compiler uses those annotations to help you find potential null reference errors in your code. There's no runtime difference between a non-nullable reference type and a nullable reference type. The compiler doesn't add any runtime checking for non-nullable reference types. The benefits are in the compile-time analysis. The compiler generates warnings that help you find and fix potential null errors in your code. You declare your intent, and the compiler warns you when your code violates that intent.

Guru Stron
  • 102,774
  • 10
  • 95
  • 132