示例代码:
public class SimpleClass
{
private NestedClass nestedClass = new NestedClass();
public class NestedClass : SimpleClass
{
}
}
// when instantiating in say.. main()
SimpleClass simpleClass = new SimpleClass();
我来自 C++ 背景,所以我很难理解这里发生的事情。具体来说,我们如何在 SimpleClass
中实例化 NestedClass
。由于理想情况下,编译器需要 SimpleClass
的完整布局才能实例化 NestedClass
,而后者又需要 SimpleClass
。它本质上有点递归。
这就是我们运行这段代码时发生的情况。我们得到一个 StackOverflow
:) 异常!
在 C++ 世界中,编译器在这种情况下会提示“incomplete type
”。
所以我的问题的关键是:
这是怎么回事,编译器是怎么布局这个类的(我知道它的实现细节,但是没有完整的类型我们怎么实例化一个对象呢?)
这个运行时异常是故意的,还是应该是编译时错误?
最佳答案
它是一个嵌套类的事实在这里无关紧要。它是一个派生 类这一事实更为重要。除了有关泛型和访问的细节(例如,嵌套类可以访问包含类的私有(private)成员)之外,嵌套类和非嵌套类之间的区别相对较小。
那么让我们证明:
class BaseClass
{
DerivedClass derived = new DerivedClass();
}
class DerivedClass : BaseClass
{
}
这仍然可以编译,但仍然会失败并返回 StackOverflowException
如果您尝试创建 BaseClass
的实例(或 DerivedClass
)。
布局很好:BaseClass
有一个字段,它是对 DerivedClass
的引用.知道“多大”也没有问题BaseClass
或 DerivedClass
是 - 实际上没有初始化方面,这绝对没问题。这里重要的是 DerivedClass
是引用类型,所以 derived
的值字段只是一个引用。
这里没有违反 C# 语言规则,设计一种语言规则来禁止这种情况而不禁止有效用例将非常困难。
这里的递归实际上与您可以对单个类执行的操作没有什么不同:
class BaseClass
{
BaseClass other = new BaseClass();
}
同样,它是完全有效的代码,但会导致堆栈溢出。
我怀疑您正在考虑的问题很容易用结构证明,尽管不涉及继承:
struct Tweedledum
{
Tweedledee dee;
}
struct Tweedledee
{
Tweedledum dum;
}
这确实失败了,因为没有合适的布局:Tweedledum
值包含 Tweedledee
直接值(value),反之亦然。不是引用:实际值。
这里的错误是:
error CS0523: Struct member 'Tweedledum.dee' of type 'Tweedledee' causes a cycle in the struct layout
error CS0523: Struct member 'Tweedledee.dum' of type 'Tweedledum' causes a cycle in the struct layout
关于c# - 嵌套类——这不是一个不完整的类型吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51909238/