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; }


Tilps said...

I think what you want here is

IThingContainer where T:Thing

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

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

Tilps said...

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.