我在C#中查看了类型值,并了解到它们不像普通引用类型那样在堆上分配.如何分配具有引用类型的结构?
例如
struct simple{
public Employee e;
public bool topEmployee;
public void printSomething()
{
Console.WriteLine("Progress " + e.GetProgressReport());
Console.WriteLine("TopEmployee " + topEmployee);
}
};
Run Code Online (Sandbox Code Playgroud)
这Employee是一堂课.e初始化时会分配给堆吗?它是否会破坏结构的意义?
小智 7
类型(值/引用)的"种类"与如何分配实例几乎没有关系.这完全取决于生命时间,并且分配的方式多于"堆"和"堆栈".阅读关于价值类型的真相.
但是在你的问题有意义的情况下:struct的成员类型不会影响struct实例的分配方式,因为它们不会影响对象的生命周期.顺便说一句,课程也是如此.
该成员e将是值类型对象的一部分,并在可能的位置进行分配.该成员是一个引用,因此任何实际Employee对象e引用将被分配到其他地方1.虽然听起来像是一个,但这不是一个特殊的规则; locals和类成员以及数组项的行为方式相同.它不会破坏价值类型,而是保持价值和参考类型的好处.值类型实例仍然是单独的值而不是别名,并且它们仍然具有更简单和更短的生命周期,从而可以更轻松地实现更好的分配选择.引用类型实例仍然是共享的,并且(可能)是长期存在的.
1至少在概念上和在当前的实现中; 在非常简单的情况下,优化(转义分析+分配下沉)可以合并这些分配,但我知道没有CLR这样做.
结构内存是“内联”分配的。类内存在堆上分配,并“内联”分配引用(指针)。
如果您在程序中看到名为 C 的类变量,则该变量的存储将相当于一个指针(例如 4 个字节),并且该类的实际存储将在堆上。
但是,如果您在程序中看到名为 S 的结构变量,则该变量的存储只是声明时变量的大小。没有堆为其分配存储空间。
如果C包含S,那么S将位于C的堆存储中。
如果S包含C,那么对C的引用将位于S的存储中,而C的存储位于堆上。simple这是您关于和 的问题的答案e。
因此,结构存储实际上可以位于静态内存中、堆栈上或堆上(在类内部)。类内存始终位于堆上。