【发布时间】:2019-10-15 22:10:44
【问题描述】:
我有一个基类Animal 和一个派生类Lion。每只动物都应该提到丛林之王,它总是一头狮子。因此在基类中添加了一个只读属性Lion : KingOfTheJungle。该属性在Animal的构造函数中初始化。
这个想法是首先创建Lion 对象,然后将它的引用传递给所有其他动物的构造函数。丛林只有一只狮子,所以当狮子被建造时,应该承认自己是丛林之王。问题是我无法创建Lion,因为当我将this 作为参数传递给base() 时出现编译时错误:
abstract class Animal
{
public Lion KingOfTheJungle { get; }
public Animal(Lion theKing)
{
KingOfTheJungle = theKing;
}
}
class Lion : Animal
{
public Lion() : base(this) // Error CS0027
{
}
}
我得到的错误是:
错误 CS0027 关键字“this”在当前上下文中不可用
寻找解决方法我最终在Lion 的构造函数中传递了null 而不是this,并在Animal 的构造函数中将null 插入为this:
abstract class Animal
{
public Lion KingOfTheJungle { get; }
public Animal(Lion theKing)
{
KingOfTheJungle = theKing ?? (Lion)this; // OK, but unsafe
}
}
class Lion : Animal
{
public Lion() : base(null) // OK, but not expressive
{
}
}
不过,我不喜欢这种解决方法,因为它既不具表现力,也不安全。有没有更安全或至少更优雅的方式来做同样的事情?
注意:我想保持属性 KingOfTheJungle 只读,没有 protected 设置器。动物在初始化后应该不能改变这个属性。
【问题讨论】:
-
@mjwills 我试过了,这是一个可行的解决方案。不过我并不完全热衷于它,因为它为每个派生类增加了两个职责。 1)添加行
public override Lion KingOfTheJungle { get; }和2)在其构造函数中分配属性KingOfTheJungle。 (2) 让我担心我可能会忘记它,因为它不是由编译器强制执行的,而且我有一堆派生类要实现。 -
恕我直言,这个要求需要提升一个级别。换句话说,如果丛林有一个硬性要求,即只有一头狮子是国王,并且没有其他动物可以在不知道它的国王的情况下存在,那么丛林的存在需要狮子作为构造的参数,或者存在这样的约束:没有国王,任何动物都不能加入丛林。了解其子类的基类是设计灾难;没有解决办法。
-
但是该示例不知道后代,因为它是通用的。这与 明确 依赖于 actual 类型不同。
-
当
Animal毫无疑问地知道存在后代时(总是);这是一个循环依赖。没有它的父母(动物),后代(狮子)就不能存在,没有国王(又名狮子),动物就不能存在;这不是设计事物的好方法。\
标签: c# inheritance constructor compiler-errors