Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is Unknown Nullability in C# 8?

In C# 8.0 we can have nullable reference types. The docs state that there are 4 types of nullability. The first 3 are quite clear but I fail to understand the point of "unknown". The docs say it is used with generics but when I try to call a method on an unconstrained variable of T type in generics it just warns as if the type is nullable. I fail to see the difference between unknown and nullable. Why does unknown exist? How does it manifest itself?

like image 955
Stilgar Avatar asked Nov 24 '19 23:11

Stilgar


People also ask

How to remove nullable warning in c#?

To remove these warnings, you need to add code to change that variable's null-state to not-null before dereferencing it.

Is string Nullable C#?

In C# 8.0, strings are known as a nullable “string!”, and so the AllowNull annotation allows setting it to null, even though the string that we return isn't null (for example, we do a comparison check and set it to a default value if null.)


1 Answers

Take the following generic method:

public static T Get<T>(T value)
{
    return value;
}

If we call it like Get<string>(s), the return is non-nullable, and if we do Get<string?>(s), it's nullable.

However if you are calling it with a generic argument like Get<T>(x) and T isn't resolved, for example it is a generic argument to your generic class like below...

class MyClass<T>
{
    void Method(T x)
    {
        var result = Get<T>(x);
        // is result nullable or non-nullable? It depends on T
    }
}

Here the compiler does not know if eventually it will be called with a nullable or non-nullable type.

There is a new type constraint we can use to signal that T cannot be null:

public static T Get<T>(T value) where T: notnull
{
    return value;
}

However, where T is unconstrained and still open, the nullability is unknown.

If these unknowns were treated as nullable then you could write the following code:

class MyClass<T>
{
    void Method(T x)
    {
        var result = Get<T>(x);
        // reassign result to null, cause we we could if unknown was treated as nullable
        result = null;
    }
}

In the case where T was not nullable, we should have got a warning. So with unknown nullability types, we want warnings when dereferencing, but also warnings for assigning potentially null.

like image 63
Stuart Avatar answered Sep 20 '22 14:09

Stuart