Guid 被认为是值类型还是引用类型?

Posted

技术标签:

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

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

这对吗?

Guid uid = new Guid();

Guid 是否存储在堆上?

【问题讨论】:

【参考方案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】:

这是一个值类型。

http://msdn.microsoft.com/en-us/library/system.guid.aspx

【讨论】:

【参考方案5】:

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

【讨论】:

您可能希望将枚举添加到值类型列表中。【参考方案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
*/

【讨论】:

以上是关于Guid 被认为是值类型还是引用类型?的主要内容,如果未能解决你的问题,请参考以下文章

Java是值传递还是引用传递?

字符串是值类型还是引用类型?

关于接口是值类型还是引用类型的猜测

函数在 Swift 中是值类型还是引用类型?为啥?

Java的参数传递是值传递还是引用传递?

unity 传递数组是值传递还是引用