首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >VS 2022 17.1不会构建C# 10结构(CS8983)。17.0.5喜欢。发生了什么?

VS 2022 17.1不会构建C# 10结构(CS8983)。17.0.5喜欢。发生了什么?
EN

Stack Overflow用户
提问于 2022-02-16 15:55:36
回答 2查看 1.2K关注 0票数 6

我在VS2022上建立了这个VS2022结构,直到昨晚我把版本从17.0.5升级到17.1

代码语言:javascript
复制
internal struct RoutineSettings
{
    public bool Show { get; set; } = true;
    public ShapeType PreferredShapeType { get; set; } = ShapeType.None;
}

(ShapeType只是一个枚举)。

升级之后,我得到以下错误:

代码语言:javascript
复制
error CS8983: A 'struct' with field initializers must include an explicitly declared constructor.

这个解释很直截了当。但是,由于这段代码在我感到困惑之前执行得很好。

  1. 编译器错了吗?
  2. 是编译器一直没有检查的一个真正的语言要求吗?

如果正确的答案是#2,这就引出了为什么这是一个要求的问题?为什么需要它?因为当我“修复”它的时候,修复似乎毫无意义。我刚刚添加了一个空的默认构造函数:

代码语言:javascript
复制
internal struct RoutineSettings
{
    public RoutineSettings() { }
    public bool Show { get; set; } = true;
    public ShapeType PreferredShapeType { get; set; } = ShapeType.None;
}

现在我的代码又重新构建了。我为什么要用这个,因为它什么都不做?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-02-16 16:34:48

在以前的版本中,这确实是一个编译器错误。直到C# 9.0,结构不允许有默认的ctor,而且它实际上没有生成,不像类那样,在没有定义构造函数的情况下自动生成默认的ctor。这允许在不调用代码的情况下创建值类型(只需使内存无效)。因此,很明显,他们想要显式地进行这种改变,因为它确实改变了生成的代码,不管默认构造函数是否存在。请注意,在您的示例中,默认构造函数不是空的,因为任何字段初始化器都是隐式添加到构造函数代码中的。因此,在C# 10中,当声明构造函数时,会生成构造函数,否则就会离开生成的IL。

还请注意,在使用此功能时存在许多缺陷。在分配结构的数组时,仍未执行默认的ctor:

代码语言:javascript
复制
        [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/

票数 5
EN

Stack Overflow用户

发布于 2022-02-20 08:47:23

这不是一个bug,而是C#的一个新的设计选择:

https://github.com/dotnet/sdk/issues/23971

解决方案:

定义一个无公共参数的构造函数,它将解决这个问题。

例如,在此之前:

代码语言:javascript
复制
public struct Abc
{
     public int Num1 = 5;
}

之后:

代码语言:javascript
复制
public struct Abc
{
     public int Num1 = 5;
     public Abc() {} // <--- Parameter-less default constructor
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71145085

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档