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
而不是通过构造函数。
到目前为止我已经尝试过:
覆盖 Constructor
:
Can't override constructor
在 Set-Accessor
中实现 if(height >= 50
)
如果我在 Main-Program
中创建一个带有构造函数的对象则不起作用
在主代码中实施障碍,使高度永远不会超过 50
如果我以后想要 CannibalGhost
的新对象(而且是一团糟)
则不起作用
这样写 CannibalGhost
不会派生自 Ghost
所以我可以编写一个新的构造函数和 set-Accessor
上限为 50。
它有效,但我希望 CannibalGhosts
也成为 Ghost(派生自 Ghost)
总结:
如何将 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
真的与Ghost
有is-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;
}
}
}
CannibalGhost : Ghost (CannibalGhost dervies from Ghost)
CannibalGhost
可以吃掉任何种类的幽灵并将它们的身高加到他的身高上。但是 Ghosts
应该可以随心所欲,而 CannibalGhosts
最多只能达到 50 的高度。它在任何情况下都不能超过。不通过。 set-accessor
而不是通过构造函数。
到目前为止我已经尝试过:
覆盖
Constructor
:Can't override constructor
在
中实现 if(Set-Accessor
height >= 50
)如果我在
中创建一个带有构造函数的对象则不起作用Main-Program
在主代码中实施障碍,使高度永远不会超过 50
如果我以后想要
则不起作用CannibalGhost
的新对象(而且是一团糟)这样写
CannibalGhost
不会派生自Ghost
所以我可以编写一个新的构造函数和
set-Accessor
上限为 50。 它有效,但我希望CannibalGhosts
也成为 Ghost(派生自 Ghost)
总结:
如何将 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
真的与Ghost
有is-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;
}
}
}