Upcasting through covariant interfaces in a constrained generic C# method

Here's a subtle one. Assume you have the appropriate “using System.Collections.Generic;” clause included somewhere up above. Can you spot what's wrong with this code?

interface ITestInterface
{
}

class TestClass<T>
    where T : ITestInterface
{
    public void TestMethod()
    {
        IReadOnlyList<T> x = null;
        IReadOnlyList<ITestInterface> y = x;
    }
}

Seems reasonable, right? An IReadOnlyList is covariant in its stored type, so given that T is constrained to be an ITestInterface, assigning such a list of T to a list of ITestInterface should be fine. And yet, compiling this code will fail at “y = x”, being unable to implicitly convert the types.

After some hair-pulling, I eventually worked out that the solution is to add “class” to the constraints on T. It would seem that, otherwise, the compiler will assume that the generic type T will not have any kind of inheritance for which covariance will be relevant. So it doesn't consider that, and the cast fails.


Comment to add? Send me a message: <brendon@quantumfurball.net>

← Previous | Next →