I have four interfaces:
public interface IBasicBoat
{
Hull BoatHull { get; set; }
}
public interface ISailBoat : IBasicBoat
{
List<Sail> Sails { get; set; }
}
public interface IMotorBoat : IBasicBoat
{
Engine Motor { get; set; }
}
public interface IGenericBoat : ISailBoat, IMotorBoat
{
}
and one class:
public class GenericBoat : IGenericBoat
{
public Hull BoatHull { get; set; }
public List<Sail> Sails { get; set; }
public Engine Motor { get; set; }
}
I want my algorithm to work differently on ISailBoats and IMotorBoats.
Say I have these two objects:
ISailBoat z_objSailBoat = new GenericBoat()
{
BoatHull = new Hull(),
Sails = new List<Sail>()
};
IMotorBoat z_objMotorBoat = new GenericBoat()
{
BoatHull = new Hull(),
Motor = new Engine()
};
and this method:
public void CheckBuoyancy(IBasicBoat p_objBoat)
{
// [...]
}
that is called twice: CheckBuoyancy(z_objSailBoat) and CheckBuoyancy(z_objMotorBoat).
Inside CheckBuoyancy(), I want to be able to tell whether p_objBoat is an ISailBoat so I can check the sails.
I've tried
if (p_objBoat is ISailBoat z_objSailBoatToCheck)
{
// do something with z_objSailBoatToCheck.Sails
}
but both z_objSailBoat and z_objMotorBoat pass that test.
- Why does
z_objMotorBoat is ISailBoatreturn true? (1a. Is it becausez_objMotorBoatis created as aGenericBoat, or is it more complicated?) - How can I check whether
p_objBoatis anISailBoat?
The obvious solution to 2. would be to create more classes like SailBoat and MotorBoat so I'd have two different constructors, but I'd like to avoid that. (If only because my actual case is noticeably more complicated.)
The reason is that GenericBoat implements both interfaces and runtime will always evaluate it that way.
You might check that by revisiting the code.
Interfaces:
Classes:
Usage: