Search code examples
c#genericscovariancedowncast

Cannot convert object of base instance to derived type (generics usage)


I have a generic version of an interval with start and end, and a concrete class that uses DateTime.

The generic version defines an Empty value for convenience. The problem comes when I run the this code.

It complaints in the only line of the Main method:

Unable to cast object of type 'Interval`1[System.DateTime]' to type 'DateTimeInterval'.

It complaints that an instance cannot be converted to my desired type. Why?? I can't understand this restriction.

void Main()
{
    DateTimeInterval p = (DateTimeInterval)DateTimeInterval.Empty;
}

class Interval<T>
{
    public Interval(T start, T end)
    {       
        Start = start;
        End = end;
    }
    
    public T Start { get; set; }
    public T End { get; set; }
    
    public static Interval<T> Empty = new Interval<T>(default, default);
}

class DateTimeInterval : Interval<DateTime> 
{
    public DateTimeInterval(DateTime start, DateTime end):base(start, end)
    {       
    }   
}

Solution

  • This issue has nothing to do with variance and generics. Next code will give you the same error:

    class Interval1
    {
        public static Interval1 Empty = new Interval1();
    }
    
    class DateTimeInterval1 : Interval1
    {
    }
    
    DateTimeInterval1 p = (DateTimeInterval1)DateTimeInterval1.Empty;
    

    Reason being that Empty is instance of Interval not DateTimeInterval, so it can't be cast to DateTimeInterval.