我一直在阅读有关 C# 中的嵌套类型的内容,我只是有一个关于它们在内存中的位置的一般性问题。由于嵌套类型的行为类似于静态成员或命名空间,您可以在其中访问该类型并创建该类型的实例,如下所示:
Container.Nested nest = new Container.Nested();
public class Container
{
public class Nested
{
private Container? parent;
public Nested()
{
}
public Nested(Container parent)
{
this.parent = parent;
}
}
}
这是来自有关嵌套类型的 C# 文档的底部:https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/nested-types
现在这个嵌套对象是 Container.Nested 类的一个实例,它是一个引用类型,因此对象引用位于堆栈上,实际数据位于堆上。难道此时Container类根本不在内存中,只有Container类的一个成员在堆内存中吗?我们正在创建一个类成员的实例,但父类本身没有实例化,所以基本上我们只有一个 Container.Nested 的对象在堆上?
嵌套类型纯粹是组织性的;给定类型
Foo
和嵌套类型 Foo.Bar
,除了您自己创建的之外,它们之间不存在任何 instance 关系。创建 Bar
并不意味着您还创建了关联的 Foo
实例 - Foo
可以是 static
、abstract class
,甚至 interface
(取决于运行时)。
现在这个嵌套对象是
类的实例,该类是引用类型,因此对象引用位于堆栈上,实际数据位于堆上。Container.Nested
对象引用可以位于任何位置(堆或堆栈),但是
Container.Nested
实例的实际内容很可能位于堆上。实际上,堆和堆栈是实现细节,通常过多担心事物的位置是没有用的,除非您真的需要知道。
此时
类是否根本不在内存中,只有Container
类的成员在堆内存中?Container
类本身(元数据、可执行代码等)位于单独的内存块中;类的实例可能位于堆上,但在这种情况下,不会创建Container
实例,除非您自己这样做(使用带有实例的第二个构造函数)。 我们正在创建一个类成员的实例,但父类本身没有实例化,所以基本上我们在堆上只有一个
Container.Nested
的对象?
是的,基本上;除非您自己做,即
new Container.Nested(new Container())
,在这种情况下,您将各拥有一个。