I have a generic class that should operate on (non-nullable) reference and value types (parameters, returns ...) but internally needs fields that can be null.
using System;
public class Gen<T> // where T : struct
{
public class Data
{
public T? t;
}
public static void Write(string s)
{
Data d = new Data();
Console.WriteLine("Default of {0} is {1}", s, d.t == null ? "null" : "NOT null");
}
// ... other stuff that uses T and not T? like
// public T DoSomething(T value) ...
}
static class Program
{
static void Main(string[] args)
{
Gen<int>.Write("int?");
Gen<string>.Write("string?");
}
}
This code does not produce any errors or warnings when compiled (.NET 5) with nullable enabled. However the behavior is not as I have expected.
Default of int? is NOT null
Default of string? is null
While playing around searching for a solution, I discovered that when the where T : struct constraint is added (and Gen.Write() removed), the behavior changes to
Default of int? is null
It's odd that a constraint changes the behavior.
Does anybody know a elegant solution to write such a generic class? Using a custom Nullable class that supports reference types too or a separate bool flags for every T? filed is a bit tedious.