patterncsharpMinor
How would you improve this object model design to get around Covariance Issues with ObjectModel.Collection<T>?
Viewed 0 times
thisaroundyouissueswithdesignobjectmodelcollectionimprovewould
Problem
Consider the following simple relationship.
Code
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 & 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
Another problem is serialization, you can alter the above to store and duplicate the inner
Any other suggestions on how to make this more Developer Friendly object model where things happen as you'd expect them to?
Code
[DataContract(Name = "Wheel")]
public class Wheel { }
[DataContract(Name = "OffRoadWheel")]
public class OffRoadWheel : Wheel { }
[DataContract(Name = "RoadVehicle")]
public class RoadVehicle
{
public Collection Wheels { get; private set; }
public RoadVehicle()
{
Wheels = new Collection();
}
}
[DataContract(Name = "Truck")]
public class Truck : RoadVehicle
{
public Collection OffRoadWheels { get; private set; }
public Truck()
{
OffRoadWheels = new Collection();
}
}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 & 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 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 TruckAny other suggestions on how to make this more Developer Friendly object model where things happen as you'd expect them to?
Solution
I think the model here is broken. If you have a
One way to make it work is to make the collection immutable (e.g.
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). This can be a reasonable solution if you're okay with setting the wheels only in the constructor.Context
StackExchange Code Review Q#19188, answer score: 2
Revisions (0)
No revisions yet.