C#中struct的引用类型

时间:2014-03-31 08:01:24

标签: c#

我正在使用C#中的类型值,并了解到它们不像普通引用类型那样在堆上分配。如何分配具有引用类型的结构?

e.g。

        struct simple{
            public Employee e;
            public bool topEmployee;
            public void printSomething()
            {
                Console.WriteLine("Progress " + e.GetProgressReport());
                Console.WriteLine("TopEmployee " + topEmployee);
            }
        };

Employee是一个类。初始化时e会分配给堆吗?它是否会破坏结构的意义?

3 个答案:

答案 0 :(得分:7)

类型(值/引用)的“种类”与实例的分配方式无关。这完全取决于生命时间,并且分配的方式多于“堆”和“堆栈”。阅读The Truth About Value Types

但是你的问题是有道理的:struct的成员类型不会影响struct实例的分配方式,因为它们不会影响对象的生命周期。顺便说一句,课程也一样。

成员e将成为值类型对象的一部分,并在其可能的位置进行分配。该成员是引用,因此任何实际的Employee对象e引用将被分配到其他地方 1 。虽然听起来像是一个,但这不是一个特殊的规则; locals和类成员以及数组项的行为方式相同。它不会破坏价值类型,而是保持价值和参考类型的好处。值类型实例仍然是单独的值而不是别名,并且它们仍然具有更简单和更短的生命周期,从而可以更轻松地实现更好的分配选择。参考类型实例仍然是共享的,并且(可能)是长寿命的。

1 至少从概念上和在当前的实现中;在非常简单的情况下,优化(转义分析+分配下沉)可以合并这些分配,但我没有注意到CLR。

答案 1 :(得分:1)

结构存储器“在线”分配。类内存在堆上分配,引用(指针)分配在“内联”。

如果在程序中看到一个名为C的类变量,该变量的存储将等同于一个指针(比如4个字节),并且该类的实际存储将在堆上。

但是如果在程序中看到一个名为S的结构变量,那么该变量的存储就是声明点处变量的大小。没有堆分配存储空间。

如果C包含S,那么S将位于C的堆存储中。

如果S包含C,则对C的引用将位于S的存储中,并且C的存储位于堆上。这是关于simplee

的问题的答案

因此,struct storage实际上可以在静态内存中,堆栈上或堆上(在类中)。类内存总是在堆上。

答案 2 :(得分:0)

引用变量“e”将在分配结构的任何地方分配(例如,未装箱的结构类型的局部变量很可能在堆栈上)。 'e'所指向的Employee实例将在堆上分配。这可能因.NET实现而异,但很可能适用于所有当前的实现。