What does null! statement mean?

  • A+
Category:Languages

I've recently seen the following code:

public class Person {     //line 1     public string FirstName { get; }     //line 2     public string LastName { get; } = null!;     //assign null is possible     public string? MiddleName {get; } = null;      public Person(string firstName, string lastName, string middleName)     {         FirstName = firstName;         LastName = lastName;         MiddleName = middleName;     }      public Person(string firstName, string lastName)     {         FirstName = firstName;         LastName = lastName;         MiddleName = null;     } } 

Basically I try to dig into new c# 8 features. One of them is NullableReferenceTypes. Actually there're a lot of articles and information about it already. E.g. this article is quite good. But I din't find any information about this new statement null! Can someone provide to me explanation for it ? Why I need to use this ? And what is difference between line1 and line2 ?

 


What is the ! operator when used on a type?

The ! operator, when used on a type, is called the Null Forgiving Operator [docs].

Typical usage

void LogPerson(Person person) {     Console.WriteLine(person.MiddleName.Length);  // WARNING: may be null     Console.WriteLine(person.MiddleName!.Length); // No warning } 

Assuming MiddleName is a nullable property

This operator basically turns off the compiler null checks.

Inner workings

Using this operator tells the compiler that something that could be null is safe to be accessed. You express the intent to "not care" about null safety in this instance.

It basically makes a nullable value non-nullable. It is, therefore, the "opposite" of the ? operator.

null = A null value = Can not be assigned to a non-nullable property.

null! = Not a null value = Can be assigned to a non-nullable property.

WARNING The ! operator only turns off the compiler-checks - At runtime, the value may still be null.

So what does null! mean?

It tells the compiler that null is not a null value. Sounds weird, doesn't it?

Picking apart what is happening here.

public string LastName { get; } = null!; 

This line defines a non-nullable class property named LastNameof type string. Since it is non-nullable you can technically not assign null to it - obviously.

But you do just that by using the ! operator. Because null! is not null - as far as the compiler is concerned.

This is an Anti-Pattern.

You should try to never use the ! Null-Forgiving-Operator. It negates the effects of null-safety you get guaranteed by the compiler.

Using the ! operator will create very hard to find bugs. If you have a property that is marked non-nullable, you will assume you can use it safely. But at runtime, you suddenly run into a NullReferenceException and scratch your head. Since a value actually became null after bypassing the compiler-checks with !.

By using a non-nullable type you express that this property is not intended to be null. If you then allow null to be assigned to it anyway - then what is the point in trying to write null-safe code anyway?

Why does this operator exist then?

  • In some edge cases, the compiler is not able to detect that a nullable value is actually non-nullable.
  • Easier legacy code-base migration.
  • In some cases, you just don't care if something becomes null

To allow you to build the project you can use this operator.

So what is the difference between line1 and line2 then?

Line1: public string FirstName { get; }

Line2: public string LastName { get; } = null!;

Line1 and Line2 are the same as far as null-safety is concerned. They both define a property that is not non-nullable. The difference is that in Line2 you assign null to the non-nullable property by force.

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: