答案 0 :(得分:1)
你知道宇宙飞船必须有尺寸;将Size放在基类中,并在那里的访问器中实现验证检查。
我知道这似乎过分关注您的具体实施,但这里的重点是您的期望并不像您预期的那样脱钩;如果你对派生类中某些东西的基类有一个期望,你的基类正在对派生类提出一个基本的期望,提供一个实现;也可以将该期望直接迁移到基类,在那里您可以更好地管理约束。
答案 1 :(得分:1)
您可以执行类似C ++ STL traits类的操作 - 实现一个通用SpaceBase<Ship, Traits>
,它有两个参数化Type
s - 一个定义SpaceShip
成员,另一个约束{ {1}}及其SpaceBase
使用SpaceShip
类来封装基础的特征,例如它可以包含的船舶的限制。
答案 2 :(得分:1)
INotifyPropertyChanging
界面是为数据绑定而设计的,这解释了为什么它没有你正在寻找的能力。我可能会尝试这样的事情:
interface ISpacebaseInterceptor<T>
{
bool RequestChange(T newValue);
void NotifyChange(T newValue);
}
答案 3 :(得分:1)
答案 4 :(得分:1)
您希望对操作应用约束,但将其应用于数据。
首先,为什么允许更改Starport.MaximumShipSize
?当我们“调整大小”时,Starport
不应该所有的船都起飞吗?
这些问题是为了更好地理解需要做什么(并且没有“对与错”的答案,有“我的和你的”)。
从其他角度看问题:
public class Starport
{
public string Name { get; protected set; }
public double MaximumShipSize { get; protected set; }
public AircarfDispatcher GetDispatcherOnDuty() {
return new AircarfDispatcher(this); // It can be decoupled further, just example
}
}
public class Spaceship
{
public double Size { get; private set; };
public Starport Home {get; protected set;};
}
public class AircarfDispatcher
{
Startport readonly airBase;
public AircarfDispatcher(Starport airBase) { this.airBase = airBase; }
public bool CanLand(Spaceship ship) {
if (ship.Size > airBase.MaximumShipSize)
return false;
return true;
}
public bool CanTakeOff(Spaceship ship) {
return true;
}
public bool Land(Spaceship ship) {
var canLand = CanLand(ship);
if (!canLand)
throw new ShipLandingException(airBase, this, ship, "Not allowed to land");
// Do something with the capacity of Starport
}
}
// Try to land my ship to the first available port
var ports = GetPorts();
var onDuty = ports.Select(p => p.GetDispatcherOnDuty())
.Where(d => d.CanLand(myShip)).First();
onDuty.Land(myShip);
// try to resize! But NO we cannot do that (setter is protected)
// because it is not the responsibility of the Port, but a building company :)
ports.First().MaximumShipSize = ports.First().MaximumShipSize / 2.0