我有下一个代码:
struct T
{
public T(int u)
{
this.U = 10; //Errors are here
}
public int U { get; private set; }
}
C#编译器在规定的行中给出了一对错误: 1)在将控制权返回给调用者之前,必须完全分配自动实现的属性“TestConsoleApp.Program.T.U”的备份字段。考虑从构造函数初始化程序中调用默认构造函数。 2)在将所有字段分配给
之前,不能使用'this'对象我做错了什么?帮帮我理解。
答案 0 :(得分:73)
来自C#规范:
10.7.3自动实现的属性
将属性指定为自动实现的属性时, 隐藏的支持字段可自动用于该属性, 并且实现访问器以读取和写入访问器 支持领域。
[删除]
由于无法访问支持字段,因此可以读取和写入 只能通过属性访问器,甚至在包含类型中。
[删除]
这个限制也意味着结构类型的明确赋值 具有自动实现的属性只能使用 结构的标准构造函数,因为分配给属性 本身需要明确分配结构。这意味着 用户定义的构造函数必须调用默认构造函数。
所以你需要这个:
struct T
{
public T(int u)
: this()
{
this.U = u;
}
public int U { get; private set; }
}
答案 1 :(得分:19)
嗯,首先你要创建一个可变结构 - 这几乎总是一个非常糟糕的主意。可变结构有时可以以您不期望的方式运行。好吧,它只是私有可变,但是你编写代码来改变它是一个不好的迹象。
第二个错误的原因是,在分配了所有字段之前,您不能使用结构的任何属性或方法,因此您需要链接到隐式无参数构造函数:
public T(int u) : this()
{
this.U = 10;
}
编译器要求任何构造函数都保留所有明确分配的字段(这就是为什么你之前得到第一个错误;编译器不“知道”属性为字段赋值) - 通过链接到this()
,您确保当您到达构造函数体时,所有字段已经明确分配,您无需担心关于它。
但是,除非你实际想要允许变异,否则我建议你把它变成一个真正的只读属性:
struct T
{
private readonly int u;
public T(int u)
{
this.u = 10;
}
public int U { get { return u; } }
}
现在它更加明显你甚至不想在结构本身中改变它。
答案 2 :(得分:4)
添加对默认构造函数的调用:
public T(int u) : this()
{
this.U = 10;
}
答案 3 :(得分:2)
你必须在这里使用默认构造函数:
struct T
{
public int U { get; private set; }
public T(int u) : this()
{
U = 10;
}
}
答案 4 :(得分:0)
从C#6开始,这不再是问题,并且可以正确编译。看here