【问题标题】:Is Guid considered a value type or reference type?Guid 被认为是值类型还是引用类型?
【发布时间】:2011-01-21 14:24:54
【问题描述】:

Guids 是使用 new 关键字创建的,这让我觉得它是一种引用类型。

这对吗?

Guid uid = new Guid();

Guid 是否存储在堆上?

【问题讨论】:

    标签: c# .net guid value-type reference-type


    【解决方案1】:

    Guid 是一种值类型。

    MSDN。请注意,Guid 是 struct。所有结构都是Value Types

    【讨论】:

    • 当然 System.ValueType 除外,它实际上是一个类 :)
    • @JaredPar:没错,但它也是抽象的,所以没有实例化的危险。
    【解决方案2】:

    您可以自己查看 Guid 的定义:

    public struct Guid ...
    

    或者你可以这样测试:

    bool guidIsValueType = typeof(Guid).IsValueType;
    

    引用:“GUID 是使用 new 关键字创建的,这让我觉得它是一种引用类型。”

    结构也可以有构造函数,例如new DateTime(2012, 12, 23)

    【讨论】:

    • 不,这是一个值类型 -> 请参阅@Randolpho 的答案
    • @CodingYourLife 实际上,你读错了答案。
    【解决方案3】:

    GUID 是使用 new 关键字创建的,这让我觉得它是一种引用类型。

    别这么想了。值类型也可以有构造函数。这是完全合法的,虽然很奇怪,说

    int x = new int();
    

    这与将零分配给 x 相同。

    这是正确的吗?

    不。

    GUID 是否存储在堆上?

    是的。指南也存储在堆栈中。

    请注意,下面的分析假设 CLI 的实现是在 Windows 上运行的 Microsoft“桌面”或“Silverlight”CLR。我不知道其他版本的 CLI 做了什么,它们在 Mac 上做了什么,等等。如果您需要知道在其他实现中是否有特定的内存块存储在堆栈中,您必须询问那些在这些实现方面的专家。

    Guid 在以下情况下存储在堆栈中:

    (1) 当 Guid 是正在进行的计算的“临时”结果或被用作方法的参数时。例如,如果您有一个方法调用 M(new Guid()),那么新 Guid 的临时存储空间将在堆栈上分配。

    (2) 当 Guid 是一个局部变量时,它 (a) 不在迭代器块中,(b) 不是匿名方法或 lambda 表达式的封闭外部变量。

    在所有其他情况下,Guid 不存储在堆栈中。当 Guid 是引用类型的字段、数组的元素、匿名方法或 lambda 表达式的封闭局部或迭代器块中的局部时,Guid 将存储在堆中。

    Guid 也可以既不存储在 GC 堆中也不存储在堆栈中。 Guid 可能存储在完全非托管的内存中,通过不安全的指针算法访问。

    我很好奇为什么您如此关心 guid 的位是在堆栈上还是在堆上。有什么区别?

    【讨论】:

    • 好吧,现在很明显 guid 可以存储在任何地方,我想没关系。
    • 在编写软实时应用程序(动画、游戏、一些 UI 工作)时,通常需要在软件的特定“循环”或迭代中减少、摊销或消除 GC 分配。这样做会减少或消除这些循环中的 GC 收集,这会导致用户可见的动画“卡顿”。因此,知道是否需要特定的代码行“分配”来决定何时缓存对象或使用对象池。示例:完全用 C# 编写的平滑实时物理模拟不得在碰撞或积分阶段进行分配。
    【解决方案4】:

    【讨论】:

      【解决方案5】:

      实际上是Guid。所有类型均使用new 关键字构造。您可以通过它们是 classinterfacedelegate(所有引用类型)还是 structenum(值类型)来从值类型中识别引用类型。

      【讨论】:

      • 您可能希望将枚举添加到值类型列表中。
      【解决方案6】:

      它的值类型,见下例:

      using System;                   
      public class Program
      {
          public static void Main()
          {
              Guid a1 = new Guid();
              Console.WriteLine(a1);
              Guid b1 = a1;
              Console.WriteLine(b1);
              a1 = Guid.NewGuid();
              Console.WriteLine(a1);
              Console.WriteLine(b1);
          }
      }
      
      /* OUTPUT
      00000000-0000-0000-0000-000000000000
      00000000-0000-0000-0000-000000000000
      164f599e-d42d-4d97-b390-387e8a80a328
      00000000-0000-0000-0000-000000000000
      */
      

      【讨论】:

        猜你喜欢
        • 2010-12-04
        • 2013-07-14
        • 2013-01-11
        • 2010-11-07
        • 1970-01-01
        • 2011-11-20
        • 1970-01-01
        • 2019-02-07
        • 2013-09-15
        相关资源
        最近更新 更多