【问题标题】:.net value type initialization.net 值类型初始化
【发布时间】:2012-03-05 22:06:45
【问题描述】:

内存中的值是什么,例如声明后的整数值(int),但没有初始化?在“CLR vi C#”中,Richter 写道,值类型初始化为 0,但不允许使用。 那么像这样声明变量后内存中会出现什么

int testVar;

以及初始化校验机制是如何实现的?

【问题讨论】:

    标签: c# .net clr


    【解决方案1】:

    类型使用全为零的内存进行初始化。我不知道这是否符合所有值类型的规范,所以除非你检查,否则你不能指望它。对于不同的值类型,内存中的零可能意味着不同的东西,具体取决于类型所代表的内容。

    值类型是自动初始化的,并且可以在它们是类的字段而不是局部变量时使用。据我所知,CLR 本身没有初始化检查。初始化检查由编译器执行,当使用未初始化的变量时会报告编译时错误。

    【讨论】:

    • +1 这个检查是C#编译器特性,CLR里没有这个检查
    • 所以,如果我理解正确的话,我可以编写一些 IL 代码来声明,例如,整数变量并将其用作零初始化变量?
    • 是的,我相信是的。变量的声明不是执行步骤。它在源代码中以某种方式烘焙。另一方面,初始化是执行步骤。这就是为什么您不能在声明但不初始化的行上放置断点。
    • 我刚刚检查过了。对于方法体之前的所有局部变量,局部变量的声明是一个步骤(至少在 IL 中)。
    【解决方案2】:

    据我所知,声明会根据该特定类型所需的字节数保留一些内存。这些字节理论上可以随机填充物理上占用这些特定硬件字节的任何内容。

    【讨论】:

    • 是的,声明保留了一些内存,但问题是它在初始化之前究竟存储了什么。如果我们使用int 作为类字段,它默认初始化为0。
    • 不,不能随意填写。不在 .NET 中。
    • 自从我 20 年前了解变量声明以来,情况发生了一些变化...... ;-)
    • 在 C/C++ 中,它们仍然以相同的方式工作。 Java 和 .NET 旨在以尽可能多的方式确定性,因此根据规范,内存被清零,操作员永远不会有未指定或未定义的行为。这会在某些情况下牺牲速度以换取鲁棒性。
    【解决方案3】:

    在 c# 中,某些类型允许您拥有可以具有 null 值的变量,例如 Nullable 变量 (Int32?intAux)。这种类型一开始是空的。否则,Int32 变量不允许您具有空值。

    您可以验证变量是否已初始化,执行类似 (intAux == null) 之类的操作。

    【讨论】:

    • 谢谢,但我知道这一点。我的问题是在声明变量之后但在为其赋值之前存储在内存中的内容是什么?
    • Nullable 类型被实现为具有 bool 字段 HasValue 和 normal 字段的结构。这些类型仍然用全零初始化。当 bool 为 0 时,它实际上为 false,因此 HasValue 为 false,这就是变量变为 null 的方式,这与引用类型 null 不同。
    猜你喜欢
    • 1970-01-01
    • 2011-04-25
    • 1970-01-01
    • 2010-10-04
    • 2022-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多