Search code examples
c#nullnull-forgiving-operator

Using null-forgiving for integer doesn't act like 'NotNull' in C#


int? number1;//Nullable variable
int number2;//Not nullable variable

//After a while
number1 = 100;

number2 = number1! + 1;
//Compile error: Cannot convert source type 'System.Nullable<int>' to target type 'int'

I don't want to use number1 ?? 0 etc. for not change my logic(consistency). (it can throw exceptions if number1 is null, no problem)

Doesn't ! means 'Trust me it is not null!' ?

Why does C# not trust me in this case?

I know null-forgiving basics but why does the ! operator not work here?

Why doesn't number1! act like NotNull in this case?


Solution

  • You must get the int value out of the int? through the Value property because you need a int result here. You can still use the null-forgiving operator to access this property.

    number2 = number1!.Value + 1;
    

    Note that the null-forgiving operator is not doing a cast or conversion. It only tells the compiler: "I know what I am doing, this value is not null". This suppresses the compiler warning "Nullable value type may be null."

    If you must test if the nullable int is not null, you can use pattern matching

    if (number1 is int n) {
        number2 = n + 1;
    }
    

    or you can use the null-coalescing operator if using 0 instead of null is acceptable.

    number2 = number1 ?? 0 + 1;
    

    Here number1 ?? 0 converts a null value into 0. (This might have been what you thought the ! did)

    Additional information: If you are in a nullable context, then the compiler checks whether a value can be null. If it thinks it can, e.g., because you have not tested if(number1 is not null), then it issues the warning "Nullable value type may be null.". But you might be smarter than the compiler and know that your logic ensures the value not to be null. Then you would use the null-forgiving operator to tell the compiler that everything is okay. ! only suppresses this warning. It does not influence what the code does. If you do not get the warning, then do not use the !. If you get the warning, either use the ! or use my 2nd or 3rd solution or ensure that the number is not null with the null-coalescing assignment operator number1 ??= 0;


    I would like to add that a nullable value type is very different from a nullable reference type.

    • Value type: E.g. int? is a synonym for the struct Nullable<int>.
    • Reference type: E.g. string? is the same type as string with a hint telling the compiler that we consider null to be a legal value.