样例代码:
public class SimpleClass
{
private NestedClass nestedClass = new NestedClass();
public class NestedClass : SimpleClass
{
}
}
// when instantiating in say.. main()
SimpleClass simpleClass = new SimpleClass();
我来自C ++,所以我很难理解这里发生的事情。具体来说,我们如何在
NestedClass
内部实例化SimpleClass
。因为理想情况下,编译器将需要SimpleClass
的完整布局才能实例化NestedClass
,而后者又需要SimpleClass
。它本质上是递归的。这就是我们运行此代码时发生的情况。我们得到一个
StackOverflow
:)异常!在C ++世界中,在这种情况下,编译器会哭“
incomplete type
”。因此,我的问题的症结在于:
这是怎么回事,编译器如何布局此类(我知道其实现细节,但是如果没有完整的类型,我们如何实例化一个对象?)
这个运行时异常是故意的,还是应该是编译时错误的东西?
最佳答案
它是嵌套类的事实在这里是无关紧要的。它是派生类的事实更为重要。除了有关泛型和访问的详细信息(例如,可以访问包含类的私有成员的嵌套类)之外,嵌套类和非嵌套类之间的区别相对较小。
因此,让我们展示一下:
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
值,反之亦然。没有参考:实际值。这里的错误是:
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/