C# generic type constraint for everything nullable

jkammerer picture jkammerer · Nov 7, 2013 · Viewed 55k times · Source

So I have this class:

public class Foo<T> where T : ???
{
    private T item;

    public bool IsNull()
    {
        return item == null;
    }

}

Now I am looking for a type constraint that allows me to use everything as type parameter that can be null. That means all reference types, as well as all the Nullable (T?) types:

Foo<String> ... = ...
Foo<int?> ... = ...

should be possible.

Using class as the type constraint only allows me to use the reference types.

Additional Information: I am writing a pipes and filters application, and want to use a null reference as the last item that passes into the pipeline, so that every filter can shut down nicely, do cleanup, etc...

Answer

Matthew Watson picture Matthew Watson · Nov 7, 2013

If you are willing to make a runtime check in Foo's constructor rather than having a compile-time check, you can check if the type is not a reference or nullable type, and throw an exception if that's the case.

I realise that only having a runtime check may be unacceptable, but just in case:

public class Foo<T>
{
    private T item;

    public Foo()
    {
        var type = typeof(T);

        if (Nullable.GetUnderlyingType(type) != null)
            return;

        if (type.IsClass)
            return;

        throw new InvalidOperationException("Type is not nullable or reference type.");
    }

    public bool IsNull()
    {
        return item == null;
    }
}

Then the following code compiles, but the last one (foo3) throws an exception in the constructor:

var foo1 = new Foo<int?>();
Console.WriteLine(foo1.IsNull());

var foo2 = new Foo<string>();
Console.WriteLine(foo2.IsNull());

var foo3= new Foo<int>();  // THROWS
Console.WriteLine(foo3.IsNull());