我有四个接口:
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
{
}
还有一堂课:
public class GenericBoat : IGenericBoat
{
public Hull BoatHull { get; set; }
public List<Sail> Sails { get; set; }
public Engine Motor { get; set; }
}
我希望我的算法在
ISailBoat
s 和 IMotorBoat
s 上以不同的方式工作。
假设我有这两个对象:
ISailBoat z_objSailBoat = new GenericBoat()
{
BoatHull = new Hull(),
Sails = new List<Sail>()
};
IMotorBoat z_objMotorBoat = new GenericBoat()
{
BoatHull = new Hull(),
Motor = new Engine()
};
这个方法:
public void CheckBuoyancy(IBasicBoat p_objBoat)
{
// [...]
}
被调用两次:
CheckBuoyancy(z_objSailBoat)
和CheckBuoyancy(z_objMotorBoat)
。
在
CheckBuoyancy()
内部,我希望能够判断 p_objBoat
是否是 ISailBoat
,以便我可以检查帆。
我已经尝试过了
if (p_objBoat is ISailBoat z_objSailBoatToCheck)
{
// do something with z_objSailBoatToCheck.Sails
}
但是
z_objSailBoat
和 z_objMotorBoat
都通过了该测试。
z_objMotorBoat is ISailBoat
返回true?
(1a. 是因为z_objMotorBoat
被创建为GenericBoat
,还是更复杂?)p_objBoat
是否是ISailBoat
?2. 的明显解决方案是创建更多类,如
SailBoat
和 MotorBoat
这样我就有两个不同的构造函数,但我想避免这种情况。 (如果只是因为我的实际情况明显更复杂。)
原因是 GenericBoat 实现了这两个接口,并且运行时将始终以这种方式对其进行评估。
您可以通过重新访问代码来检查这一点。
接口:
public interface IBoat
{
Hull BoatHull { get; set; }
Buoyancy CheckBuoyancy();
}
public interface ISailBoat : IBoat
{
List<Sail> Sails { get; set; }
}
public interface IMotorBoat : IBoat
{
Engine Motor { get; set; }
}
课程:
public abstract class Boat : IBoat
{
Hull BoatHull { get; set; }
public virtual Buoyancy CheckBuoyancy() {
// Calculate buoyancy if both boat types use same algorithm.
// If not you might want to change virtual modifier to abstract to force each concrete type to implement its own calculation.
}
}
public class MotorBoat : Boat, IMotorBoat
{
Engine Motor { get; set; }
public override Buoyancy CheckBuoyancy() {
// In case you need to use different way to calculate buoyancy
}
}
public class SailBoat : Boat, ISailBoat
{
List<Sail> Sails { get; set; }
public override Buoyancy CheckBuoyancy() {
// In case you need to use different way to calculate buoyancy
}
}
用途:
IBoat boat1 = new SailBoat()
{
BoatHull = new Hull(),
Sails = new List<Sail>()
};
IBoat boat2 = new MotorBoat()
{
BoatHull = new Hull(),
Motor = new Engine()
};
var boatBuoyancy1 = boat1.CheckBuoyancy();
var boatBuoyancy2 = boat2.CheckBuoyancy();
if(boat1 is ISailBoat sailBoat) {
var sailsCount = sailBoat.Sails.Count();
}
if(boat2 is IMotorBoat motorBoat) {
var horsePower = motorBoat.Motor.HorsePower;
}