I have multiple classes representing objects which all have bounds described by a Unity Rect field. (Zone, Room, Structure, Tunnel, Room
...)
These objects are often placed in collections. (List<Zone>, List<Room>
...)
I want to have single static utility method that will test if a single one of these overlaps any the bounds from a collection of such objects, without having to cast a List using LINQ.
public static bool BoundsOverlapsOtherBounds(Bounds bound, List<Bounds>)
How should I use C# polymorphism, interfaces, covariance to achieve this, without needing to cast List<Room>
or List<Zone>
to List<Bounds>
first?
My attempts so far have always produced "Cannot covert X to Y" compiler errors.
Because (as implied) all of these types already inherit from Bounds
, you don't need to cast List<Room>
or List<Zone>
to List<Bounds>
.
You can do this:
bool BoundsOverlapsOtherBounds<T>(Bounds bound, List<T> bounds) where T : Bounds
The generic constraint means that you can pass any List<T>
to the method as long as T
implements or inherits Bounds
.
So if you have a List<Room>
you can pass it to the method without explicitly casting it:
var rooms = new List<Room>();
var otherBounds = new Bounds();
var overlaps = BoundsOverlapsOtherBounds(otherBounds, rooms);
You don't even have to specify the generic argument because it's inferred.
If by any chance these objects don't share a common type, then it's likely a case where they should. Inheritance is a solution, but we don't need to use it to cause types to have a common characteristic. Sometimes that paints us into a corner. An interface might also make sense:
interface IHasBoundaries // not a great name?
{
Boundaries Bounds { get; }
}
That's polymorphism. Multiple forms (or types) can implement the interface, and you don't care at all about what makes them different - only what they have in common. You can write code that deals with IHasBoundaries
and in that context that's the only thing you need to know about those objects, that they implement the interface.
Then your method looks like this:
bool BoundsOverlapsOtherBounds<T>(IHasBoundaries bound, List<T> bounds)
where T : IHasBoundaries