C# 当struct未初始化时,如果我们尝试访问属性但不使用变量,编译器将给出错误

C# 当struct未初始化时,如果我们尝试访问属性但不使用变量,编译器将给出错误,c#,.net,struct,C#,.net,Struct,我对struct有一个观察。当我在Struct中声明一个属性时,如果我没有初始化该结构,则会出现以下错误-“使用未赋值的局部变量empStruct” psedou码- struct EmpStruct { private int firstNumber; public int FirstNumber { get { return firstNumber; } set { firstNumber = value; } } p

我对struct有一个观察。当我在Struct中声明一个属性时,如果我没有初始化该结构,则会出现以下错误-“使用未赋值的局部变量empStruct”

psedou码-

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;

所以我的问题是,为什么编译器在我尝试访问变量时不给出错误。(对于类,它会给出错误)。

关于字段C#语言规范说:

10.5.4字段初始化

字段的初始值,无论是静态字段还是静态字段 实例字段,是字段类型的默认值(§5.2)。它是 在此默认值之前,无法观察字段的值 初始化已经发生,因此字段永远不会“未初始化”

11.3.4默认值

但是,由于结构是不能为null的值类型,因此 结构的默认值是通过设置所有值生成的值 将类型字段设置为其默认值,将所有引用类型字段设置为 空。结构的默认值对应于返回的值 通过结构的默认构造函数(§4.1.2)


PS:对于类,它会给出错误,因为在第一个示例中,引用类型值默认为null,代码不起作用,因为必须先初始化局部变量,然后才能使用它们。没有“默认值”值;必须首先初始化它们。在使用每个局部变量之前,始终必须初始化它。例如:

EmpStruct empStruct = new EmpStruct();
empStruct.FirstNumber = 5;

类中的字段没有相同的限制。如果不显式初始化它们,它们将使用默认值自动初始化。实际上,运行时会自动调用“new EmpStruct()这就是为什么你的第二个例子有效。

在这个主题中有大量的混乱

其原理是:除非明确指定了
结构
实例的所有字段,否则不能调用该实例上的任何属性或方法

这就是为什么您的第一段代码无法编译。您正在访问一个属性,但没有明确指定所有字段

第二段代码可以编译,因为在没有明确分配所有字段的情况下访问字段是可以的

明确指定结构的一种方法是

EmpStruct empStruct = new EmpStruct();
这将调用
EmpStruct
的默认无参数构造函数,它肯定会分配所有字段

本规范的相关章节为§5.3中关于明确分配的章节,以及§11.3.8中的示例

在明确分配所构造结构的所有字段之前,不能调用任何实例成员函数(包括属性
X
Y
的集合访问器)

如果编译器的错误消息是按照

使用未明确指定的局部变量
empStruct

然后就可以清楚地知道在规范中或上搜索什么了


现在,请注意,您已经定义了一个可变结构。这是危险的,也是邪恶的。您不应该这样做。相反,添加一个公共构造函数,它允许您明确地分配
firstNumber
secondNumber
,并从
EmpStruct中删除公共setter。firstNumber
一些代码示例可能有助于更好地阐明这一点:

// 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);

关键是,编译器确切地知道当您分配一个字段时会发生什么。但是当您分配一个属性时,它可能会访问
结构
上的任何数量的其他字段。编译器不确定。因此它要求您在访问属性之前分配所有字段。

这不相关。它不适用于解释错误的原因。@Jason:它与字段和类案例有关,但与属性无关。在规范中仍然找不到答案。很抱歉,这一点都不相关。错误的原因与缺少对
EmpStruct
的明确赋值有关。您所使用的规范中的部分引用不涉及明确的赋值。请参见§5.3和§11.3.8。@Jason:我的回答主要是关于为什么
当我声明公共变量时,上面的代码工作
,而
PS
是关于为什么它在使用类而不是结构类型时不工作。与属性相关的错误无关。您从sp引用的位指定不能解释为什么可以访问
SecondVariable
而不能访问
FirstVariable
。这是这个问题的核心。这没有任何意义。为什么编译器会在第二个块中调用
new EmpStruct
,而不是在第一个块中?这个答案没有解释为什么这两个块之间存在差异我想我很难理解最初的问题,我想他说的是用结构作为局部变量,而不是用结构作为字段。