Because T is unconstrained in your case, and for unconstrained (neither to struct nor to class) generic type parameters T - T? is handled differently for value types and reference types. From the docs:
- If the type argument for
T is a reference type, T? references the corresponding nullable reference type. For example, if T is a string, then T? is a string?.
- If the type argument for
T is a value type, T? references the same value type, T. For example, if T is an int, the T? is also an int.
- If the type argument for
T is a nullable reference type, T? references that same nullable reference type. For example, if T is a string?, then T? is also a string?.
- If the type argument for
T is a nullable value type, T? references that same nullable value type. For example, if T is a int?, then T? is also a int?.
So for Foo<int> actual signature will be int Foo<int>, hence the error.
If it is suitable for you - constrain T to be either struct or class.