ulrichb/ImplicitNullability

Handle Nullable<> in generic Methods

pothos-dev opened this issue · 2 comments

If I use the Nullable<T> (or T?) type, I implicitly state the possibility of null values, otherwise I would just use T.

This is detected correctly by the analyzer, so this works:

int? myInt;
void Allowed()
{
    myInt = new int?();
}

However, when I use T? as a generic argument for a method, the analyzer gets confused.

int? myInt;

T Forward<T>(T value)
{
    return value;
}

void Disallowed()
{
    // Possible 'null' assignment to entity marked with 'NotNull' attribute
    myInt = Forward(new int?());
}

I would have to mark my generic method accordingly:

int? myInt;

[CanBeNull] T Forward<T>([CanBeNull] T value)
{
    return value;
}

void Allowed()
{
    myInt = Forward(new int?());
}

However, I would then allow nullability for reference types using this method, which I do not want.

The analyzer should allow null arguments and null return values in generic methods, if they use a Nullable<> type.

It was a conscious decision to make unconstrained generic types implicit [NotNull]. It's a tade-off between the false positives you discovered and false negatives for reference type usages (+ for parity with Fody NullGuard). See this test and the corresponding GenericsSample.

But: There is a workaround to fix your issue by defining an overload for the nullable structs.

image

Closed after long period of inactivity of question.