I have the following class:
class GenericClass<T>
{
public T? A { get; init; }
public T B { get; init; }
public GenericClass(T? a, T b)
{
A = a;
B = b;
}
}
I want to use it for any sort of T
, no matter if struct
, class
, enum
. I merely want to make sure that property A
can always be null while property B
's nullable-ness is the same as T
's. But this does not seem to work.
If I write
static void MyTestMethod()
{
var vStruct = new GenericClass<bool>(null, true);
var vNullableStruct = new GenericClass<bool?>(null, true);
var vClass = new GenericClass<string>(null, "hello");
var vNullableClass = new GenericClass<string?>(null, "hello");
var vEnum = new GenericClass<Color>(null, Color.red);
var vNullableEnum = new GenericClass<Color?>(null, Color.red);
}
where Color
is defined as enum Color { red, green, blue }
,
I get compiler error CS1503 for vStruct
and vEnum
:
Argument '1': cannot convert from
<NULL>
tobool
/Color
In both cases, the mouseover for new GenericClass<...>
shows both arguments as non-nullable although I clearly defined A
as nullable. Why?
I can add a type constraint: class GenericClass<T> where T : struct
, which will leave the two previously erroneous lines (vStruct
and vEnum
) error-free, but will mark all others as erroneous. This time with compiler error CS0453:
The type
bool?
/string
/string?
/Color
must be a non-nullable value type in order to use it as parameterT
in the generic type or methodGenericClass<T>
.
Which makes perfectly sense; they are not struct
.
But how do I make my GenericClass<T>
work for both classes and structs/enums?