我在VS2022上建立了这个VS2022结构,直到昨晚我把版本从17.0.5升级到17.1
internal struct RoutineSettings
{
public bool Show { get; set; } = true;
public ShapeType PreferredShapeType { get; set; } = ShapeType.None;
}(ShapeType只是一个枚举)。
升级之后,我得到以下错误:
error CS8983: A 'struct' with field initializers must include an explicitly declared constructor.这个解释很直截了当。但是,由于这段代码在我感到困惑之前执行得很好。
如果正确的答案是#2,这就引出了为什么这是一个要求的问题?为什么需要它?因为当我“修复”它的时候,修复似乎毫无意义。我刚刚添加了一个空的默认构造函数:
internal struct RoutineSettings
{
public RoutineSettings() { }
public bool Show { get; set; } = true;
public ShapeType PreferredShapeType { get; set; } = ShapeType.None;
}现在我的代码又重新构建了。我为什么要用这个,因为它什么都不做?
发布于 2022-02-16 16:34:48
在以前的版本中,这确实是一个编译器错误。直到C# 9.0,结构不允许有默认的ctor,而且它实际上没有生成,不像类那样,在没有定义构造函数的情况下自动生成默认的ctor。这允许在不调用代码的情况下创建值类型(只需使内存无效)。因此,很明显,他们想要显式地进行这种改变,因为它确实改变了生成的代码,不管默认构造函数是否存在。请注意,在您的示例中,默认构造函数不是空的,因为任何字段初始化器都是隐式添加到构造函数代码中的。因此,在C# 10中,当声明构造函数时,会生成构造函数,否则就会离开生成的IL。
还请注意,在使用此功能时存在许多缺陷。在分配结构的数组时,仍未执行默认的ctor:
[Fact]
public void StructCtorIsExecuted()
{
var r = new RoutineSettingsWithDefaultCtor();
Assert.Equal(10, r.PreferredShapeType);
RoutineSettingsWithDefaultCtor[] array = new RoutineSettingsWithDefaultCtor[10];
Assert.Equal(0, array[0].PreferredShapeType); // <-- When allocating an array, the default ctor is NOT executed
}
internal struct RoutineSettingsWithDefaultCtor
{
public RoutineSettingsWithDefaultCtor()
{
PreferredShapeType = 10;
}
public bool Show { get; set; } = true;
public int PreferredShapeType { get; set; } = 2;
}
}这里描述了更多的问题:https://davidshergilashvili.space/2021/09/05/c-10-struct-type-can-define-default-constructor/
发布于 2022-02-20 08:47:23
这不是一个bug,而是C#的一个新的设计选择:
https://github.com/dotnet/sdk/issues/23971
解决方案:
定义一个无公共参数的构造函数,它将解决这个问题。
例如,在此之前:
public struct Abc
{
public int Num1 = 5;
}之后:
public struct Abc
{
public int Num1 = 5;
public Abc() {} // <--- Parameter-less default constructor
}https://stackoverflow.com/questions/71145085
复制相似问题