Search code examples
c#entity-frameworkentity-framework-corec#-8.0nullable-reference-types

How can I hint the C# 8.0 nullable reference system that a property is initalized using reflection


I ran into an interesting problem when I tried to use Entity Framework Core with the new nullable reference types in C# 8.0.

The Entity Framework (various flavors) allows me to declare DBSet properties that I never initalize. For example:

    public class ApplicationDbContext : IdentityDbContext
      {
    #pragma warning disable nullable
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
          : base(options)
        { }
    #pragma warning restore nullable

        public DbSet<Probe> Probes { get; set; }
        public DbSet<ProbeUnitTest> ProbeUnitTests { get; set; }
    }

The DbContext constructor reflects over the type and initializes all of the DbSet properties, so I know that all the properties will be non-null by the conclusion of the constructor. If I omit the #pragma's i get the expected warnings because my code does not initialize these properties.

 Data\ApplicationDbContext.cs(10,12,10,32): warning CS8618: Non-nullable property 'Probes' is uninitialized.
 Data\ApplicationDbContext.cs(10,12,10,32): warning CS8618: Non-nullable property 'ProbeUnitTests' is uninitialized.

Turning off the warnings seems like a blunt instrument when all I want to do is inform the compiler that a property will not be null?

If turns out I can fool the compiler like this:

     public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
      : base(options)
    {
      Probes = Probes;
      ProbeUnitTests = ProbeUnitTests;
    }

This code has the advantage that it is very narrow -- it only applies to the specific property's initialization and will not suppress other warnings. The disadvantage is that this is nonsense code because assigning a property to itself really ought to do nothing.

Is there a preferred idiom for informing the compiler that it just does not know that the property has been initialized?


Solution

  • Whenever you want to tell the compiler "shut up, I know what I'm doing" in regards to nullable reference types, use the ! operator. You can fix your issue by declaring your properties like so:

    public DbSet<Probe> Probes { get; set; } = null!;
    public DbSet<ProbeUnitTest> ProbeUnitTests { get; set; } = null!;