我想试试这段代码:
public struct Direction
{
private int _azimuth;
public int Azimuth
{
get { return _azimuth; }
set { _azimuth = value; }
}
public Direction(int azimuth)
{
Azimuth = azimuth
}
}
但是它在编译时失败,我知道struct需要初始化它的所有字段。但我在试着理解在CLR\IL引擎盖下发生了什么。为什么它在任何其他方法\属性\this等之前需要所有字段。
谢谢。
发布于 2009-04-25 14:02:57
值类型是在堆栈上创建的(除非嵌套在引用类型中) CLR不能保证堆栈上的字段/位置会被清零(与托管堆上的字段/位置相反,托管堆上的字段/位置肯定会被清零)。因此,必须在读取它们之前对其进行写入。否则就是一个安全漏洞。
结构的默认ctor (不带参数,不允许您显式指定)将结构的所有字段置零,因此您可以在这样做后使用结构。
new BimonthlyPairStruct()
但是,当您实现参数化的ctor时,您的必须确保所有字段都已初始化-这是CLR将您的代码作为safe/验证的传递所必需的。
另请参阅: CLR via C#第二版-第188页
发布于 2009-04-06 12:57:17
这是因为结构是从System.ValueType而不是System.Object派生的,System.ValueType实现了你不能重写的默认结构,这个默认构造函数用它的默认值初始化结构中的所有字段。因此,如果您在类中实现任何参数构造器,您还将需要确保调用system.ValueType默认常量。要回答为什么它需要初始化所有的值,这是因为值存储在堆栈内存中。
发布于 2009-04-06 12:58:12
这是可行的:
public Direction(int azimuth)
{
_azimuth = azimuth;
}
从规范中:
使用
运算符调用新结构构造函数,但这并不意味着正在分配内存。结构构造函数不是动态分配对象并返回对它的引用,而是简单地返回结构值本身(通常位于堆栈上的临时位置),然后根据需要复制该值。
基本上,编译器必须看到每个字段都在构造函数中被初始化,以便它可以复制这些值,并且它不愿意检查对函数或属性的调用。
https://stackoverflow.com/questions/721246
复制相似问题