当struct未初始化时,如果我们尝试访问属性但不使用变量,则编译器会出错
我有一个关于结构的观察。 当我在Struct中声明一个属性,如果我没有初始化Struct那么它给我下面的错误 – “使用未分配的局部变量empStruct”
PSeduo代码 –
struct EmpStruct { private int firstNumber; public int FirstNumber { get { return firstNumber; } set { firstNumber = value; } } public int SecondNumber; }
Program.cs-
EmpStruct empStruct; empStruct.FirstNumber = 5;
但是当我声明公共变量时,上面的代码就可以了。
EmpStruct empStruct; empStruct.SecondNumber;
所以我的问题是为什么编译器在我尝试访问变量时不会出错。(如果是Class,它会给出错误)。
这个post里有很多混乱。
原理是这样的:在struct
的实例的所有字段都明确赋值之前,您不能在实例上调用任何属性或方法。
这就是你的第一个代码块无法编译的原因。 您正在访问一个属性,而没有明确分配所有字段。
第二个代码块进行编译,因为可以在没有明确分配所有字段的情况下访问字段。
确定分配struct
一种方法是说
EmpStruct empStruct = new EmpStruct();
这将调用EmpStruct
的默认无参数构造EmpStruct
,它将明确分配所有字段。
规范的相关部分是关于定义分配的§5.3。 并且来自§11.3.8中的示例
在构造的结构的所有字段都已明确赋值之前,不能调用实例成员函数(包括属性
X
和Y
的集合访问器)。
如果编译器错误消息是沿着的话,那将会更有帮助(嗯,Eric Lippert!)
使用未明确分配的局部变量
empStruct
。
然后很清楚在规范中或在Google上搜索什么。
现在,请注意您已定义了一个可变结构。 这是危险的,也是邪恶的。 你不应该这样做。 相反,添加一个公共构造函数,它允许您明确地分配firstNumber
和secondNumber
,并从EmpStruct.FirstNumber
删除公共setter。
关于字段 C#语言规范说:
10.5.4字段初始化
字段的初始值(无论是静态字段还是实例字段)是字段类型的默认值(第5.2节)。 在此默认初始化发生之前无法观察字段的值,因此字段永远不会“未初始化”
11.3.4默认值
但是,由于结构体是不能为null的值类型,因此结构的默认值是通过将所有值类型字段设置为其默认值并将所有引用类型字段设置为null而生成的值。 struct的默认值对应于struct的默认构造函数返回的值(第4.1.2节)。
PS:在类的情况下,它会给出错误,因为默认情况下引用类型值为null
在第一个示例中,代码不起作用,因为必须先初始化局部变量才能使用它们。 没有默认值; 必须先将它们初始化。 您必须先初始化每个局部变量,然后才能使用它。 例如:
EmpStruct empStruct = new EmpStruct(); empStruct.FirstNumber = 5;
类中的字段没有相同的限制。 如果您没有显式初始化它们,它们将使用默认值自动初始化。 实际上,运行时会自动在类中的字段上调用“new EmpStruct()”。 这就是你的第二个例子有效的原因。
一些代码示例可能有助于更好地澄清这一点:
// This works because you assign both fields before accessing anything EmpStruct empStruct; empStruct.SecondNumber = 2; empStruct.firstNumber = 1; // I made this public empStruct.FirstNumber = 3; Console.WriteLine(empStruct.FirstNumber); Console.WriteLine(empStruct.SecondNumber); // This fails because you can't use properties before assigning all the variables EmpStruct empStruct; empStruct.SecondNumber = 2; empStruct.FirstNumber = 3; // This works because you are only accessing a field that the compiler knows you've assigned EmpStruct empStruct; empStruct.SecondNumber = 2; Console.WriteLine(empStruct.SecondNumber); // This fails because you haven't assigned the field before it gets accessed. EmpStruct empStruct; Console.WriteLine(empStruct.SecondNumber);
关键是,编译器确切地知道分配字段时会发生什么。 但是,当您分配属性时,可能会访问struct
上的任意数量的其他字段。 编译器不确定。 因此,它要求您在访问属性之前分配所有字段。