How would you improve this object model design to get around Covariance Issues with ObjectModel.Collection? Consider the following simple relationship.



Code

[DataContract(Name = "Wheel")]
public class Wheel { }

[DataContract(Name = "OffRoadWheel")]
public class OffRoadWheel : Wheel { }

[DataContract(Name = "RoadVehicle")]
public class RoadVehicle
{
    public Collection&lt;Wheel&gt; Wheels { get; private set; }

    public RoadVehicle()
    {
        Wheels = new Collection&lt;Wheel&gt;();
    }
}

[DataContract(Name = "Truck")]
public class Truck : RoadVehicle
{
    public Collection&lt;OffRoadWheel&gt; OffRoadWheels { get; private set; }

    public Truck()
    {
        OffRoadWheels = new Collection&lt;OffRoadWheel&gt;();
    }
}


The Collections are configured as Read-Only and initiated in the class constructor as per FXCop recommendation CAS2227. http://msdn.microsoft.com/en-us/library/ms182327(VS.80).aspx

Now I know all the rules about Covariance &amp; Contravariance, and the varying capabilities of using Collections vs. Lists vs. Enumerables (vs. their Interface Equivalents). However the above object model creates a number of competing difficulties.

If you create a truck with 4 Off-Road Wheels, down cast it to a RoadVehicle, and then iterate the Wheels collection... it's empty.

One way around this would be to create a public new Collection&lt;Wheel&gt; Wheels property on the Truck class which on-the-fly casts the contents of the OffRoadWheel collection, but this breaks behaviour if you go to add or remove on that collection.

Another problem is serialization, you can alter the above to store and duplicate the inner Wheels and OffRoadWheels properties, but then you'd end up complete serializing both if you wanted to serialize Truck

Any other suggestions on how to make this more Developer Friendly object model where things happen as you'd expect them to?
I think the model here is broken. If you have a RoadVehicle that's actually Truck, the interface lets you to add a normal Wheel to it, which is wrong.

One way to make it work is to make the collection immutable (e.g. IEnumerable&lt;T&gt;). This can be a reasonable solution if you're okay with setting the wheels only in the constructor.