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 ISailBoat
s and IMotorBoat
s.
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 ISailBoat
return true? (1a. Is it becausez_objMotorBoat
is created as aGenericBoat
, or is it more complicated?) - How can I check whether
p_objBoat
is 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: