为什么在结构的构造函数中设置属性不起作用?

Moc*_*cco 6 c# struct properties

我有以下不允许的代码(下面的错误),为什么?

    struct A
    {
        private int b;

        public A(int x)
        {
            B = x;
        }
        public int B
        {
            get { return b; }
            set { b=value; }
        }

    }
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

在将所有字段分配给字段之前,不能使用'this'对象'Test.x'必须在控制返回给调用者之前完全分配

Jon*_*eet 5

在您可以使用任何方法或属性之前,必须明确分配结构的变量。这里有两种可能的修复方法:

1)您可以显式调用无参数构造函数:

public A(int x) : this()
{
    B = x;
}
Run Code Online (Sandbox Code Playgroud)

2)您可以使用字段而不是属性:

public A(int x)
{
    b = x;
}
Run Code Online (Sandbox Code Playgroud)

当然,第二个选项仅适用于您当前的形式 -如果您想更改结构以使用自动属性,则必须使用第一个选项。

然而,重要的是,您现在拥有了一个可变结构。这几乎总是一个非常糟糕的主意。我强烈建议你改用这样的东西:

struct A
{
    private readonly int b;

    public A(int x)
    {
        b = x;
    }

    public int B { get { return b; } }
}
Run Code Online (Sandbox Code Playgroud)

编辑:有关为什么原始代码不起作用的更多详细信息...

来自 C# 规范的第 11.3.8 节:

如果 struct 实例构造函数没有指定构造函数初始值设定项,则该this变量对应于outstruct 类型的参数

现在最初不会明确分配,这意味着您不能执行任何成员函数(包括属性设置器),直到正在构造的结构的所有第一个都被明确分配。编译器不知道或试图考虑这样一个事实,即属性设置器不尝试从另一个字段读取。这一切都是为了避免从尚未明确分配的字段中读取数据。


Ant*_*lev 0

将您的构造函数更改为:

public A(int x) :
    this()
{
    B = x;
}
Run Code Online (Sandbox Code Playgroud)

至于“为什么”,请参考11.3.8 构造函数5.3 明确赋值