9 November 2011

Interface implementation and covariance


I was a bit disappointed to discover that the following code doesn't compile in C# 4. In particular, it seems that as the 'Thing' property is only a getter on the interface, any concrete implementation should be able to return a derived type, since it can be guaranteed that anyone getting the parent type from the interface will also be able to operate on the child type.




class Thing { }

class SpecificThing : Thing { }

interface IThingContainer
{
Thing Thing { get; }
}

class SpecificThingContainer : IThingContainer
{
public SpecificThing Thing { get; set; }
}

2 comments:

  1. I think what you want here is

    IThingContainer where T:Thing

    Then
    class SpecificThingContainer : IThingContainer which can be cast to IThingContainer without difficulty.

    Sure it isn't 'nice' but it bypasses the specific problem...

    ReplyDelete
  2. I should have hit preview - all my generic parameters got eaten by the html formatting engine...

    This time with braces instead of angle brackets...

    IThingContainer{T} where T: Thing

    class SpecificThingContainer : IThingContainer{SpecificThing} which can be cast to IThingContainer{Thing} as needed.

    ReplyDelete