如何将对象限制为其某个接口进行类型测试?

问题描述 投票:0回答:1

我有四个接口:

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
都通过了该测试。

  1. 为什么
    z_objMotorBoat is ISailBoat
    返回true? (1a. 是因为
    z_objMotorBoat
    被创建为
    GenericBoat
    ,还是更复杂?)
  2. 如何检查
    p_objBoat
    是否是
    ISailBoat

2. 的明显解决方案是创建更多类,如

SailBoat
MotorBoat
这样我就有两个不同的构造函数,但我想避免这种情况。 (如果只是因为我的实际情况明显更复杂。)

c# interface type-testing
1个回答
0
投票
  1. 为什么 z_objMotorBoat is ISailBoat 返回 true? (1a. 是因为 z_objMotorBoat 是作为 GenericBoat 创建的,还是更复杂?)

原因是 GenericBoat 实现了这两个接口,并且运行时将始终以这种方式对其进行评估。

  1. 如何检查 p_objBoat 是否是 ISailBoat?

您可以通过重新访问代码来检查这一点。

接口:

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;
}
© www.soinside.com 2019 - 2024. All rights reserved.