C#:如何从派生的 class 中设置 属性 的最大值? (并且不在基础 class 中)

C#: How can I set a maximal Value of a property from a derived class? (And not in base class)

CannibalGhost : Ghost (CannibalGhost dervies from Ghost)

CannibalGhost 可以吃掉任何种类的幽灵并将它们的身高加到他的身高上。但是 Ghosts 应该可以随心所欲,而 CannibalGhosts 最多只能达到 50 的高度。它在任何情况下都不能超过。不通过。 set-accessor 而不是通过构造函数。

到目前为止我已经尝试过:

总结: 如何将 CannibalGhost 的 属性 Height 设置为最大 50,而不是在基础 class Ghost 中?

您可以构建 Ghost,使其知道在派生 class(es) 中需要进行某些验证,而无需在基础 class[= 中实现逻辑本身24=]

public class Ghost
{
    private int height;

    protected virtual bool IsValidHeight(int newHeight)
    {
        return true;
    }

    public int Height
    {
       get{ return height; }
       set
       {
           if(!IsValidHeight(value) throw new InvalidHeightException(value);
           height = value;
       }
    }
}

public class CannibalGhost 
{
    protected override bool IsValidHeight(int newHeight
    {
        return newHeight <= 50;
    }
}

也许你不想抛出异常,而是想限制你可以使该虚拟方法的高度

protected virtual int LimitHeight(int newHeight)
{
     return newHeight;
}

protected override int LimitHeight(int newHeight)
{
    return (int)Math.Min(newHeight,50);
}

那么 setter 就是

set
{
    height = LimitHeight(value);  
}

这对 Ghost 没有影响,但会将派生的 CannibalGhost 限制为 50。


事实上,这不是一个很好的解决方案。在设计基础 class 时,您无法知道所有可能需要这种验证的地方 - 这也是为什么继承会因比这个简单示例更复杂的解决方案而崩溃。

CannibalGhost真的Ghostis-a关系吗?或者它实际上是由多个 Ghost 个实例组成(一个 has-a-collection-of 关系)。在这种情况下,它的高度可以仅仅是其所有组成的 Ghost 实例的总和,限制为 50。不需要继承。也许所有幽灵都为共享行为实施 IGhost - 需要考虑的事情!

通过在基础 class 中设置高度 属性 virtual,您可以派生 classes 通过 overriding它。

示例:

public class Ghost
{
    public virtual int Height { get; set; }
}

public class CannibalGhost : Ghost
{
    private int _height;
    public override int Height
    {
        get
        {
            return _height;
        }
        set
        {
            if (value > 50)
                throw new InvalidOperationException($"A {nameof(CannibalGhost)} cannot have a height over 50");

            _height = value;
        }
    }
}