通过


解决构造函数声明中的错误和警告

本文介绍以下编译器错误:

  • CS0132“构造函数”:静态构造函数必须无参数。
  • CS0514静态构造函数不能有显式的“this”或“base”构造函数调用。
  • CS0515:不允许在静态构造函数中使用 访问修饰符。
  • CS0516构造函数“constructor”无法调用其自身。
  • CS0517“class”没有基类,无法调用基构造函数。
  • CS0522结构无法调用基类构造函数。
  • CS0526接口不能包含构造函数。
  • CS0568结构不能包含显式无参数构造函数。
  • CS0573“字段声明”:结构中不能有实例字段初始值设定项。
  • CS0710静态类不能有实例构造函数。
  • CS0768构造函数无法通过另一个构造函数自行调用。
  • CS1018应为关键字“this”或“base”。
  • CS8054枚举不能包含显式无参数构造器。
  • CS8091不能是外部的,也不能具有构造函数初始值设定项。
  • CS8861意外参数列表。
  • CS8862在具有参数列表的类型中声明的构造函数必须具有“this”构造函数初始值设定项。
  • CS8358无法使用属性构造函数,因为它具有“in”参数。
  • CS8867基类型“{0}”中找不到可访问的复制构造函数。
  • CS8868记录中的复制构造函数必须调用基的复制构造函数;如果记录继承自对象,则必须调用无参数对象构造函数。
  • CS8878复制构造函数“{0}”必须公开或受保护,因为记录未密封。
  • CS8910主构造函数与合成复制构造函数冲突。
  • CS8958无参数结构构造函数必须为“public”。
  • CS8982在“结构体”中带有参数列表声明的构造函数必须有一个“this”初始化器,用于调用主构造函数或显式声明的其他构造函数。
  • CS8983具有字段初始值设定项的“结构”必须包含显式声明的构造函数。
  • CS9105不能在此上下文中使用主构造函数参数。
  • CS9106此上下文中的类型和参数之间的标识符不明确。
  • CS9108无法使用在匿名方法、lambda 表达式、查询表达式或本地函数中具有类似 ref 类型的参数。
  • CS9109不能在实例成员内使用 refoutin 主构造函数参数。
  • CS9110无法在实例成员中使用具有类似于 ref 类型的主构造函数参数。
  • CS9111结构实例成员内的匿名方法、lambda 表达式、查询表达式和本地函数无法访问主构造函数参数。
  • CS9112匿名方法、lambda 表达式、查询表达式和结构内的本地函数无法访问实例成员内也使用的主构造函数参数。
  • CS9114:不能为只读类型的主构造函数参数赋值(在该类型的仅限 init 的资源库中或变量初始值设定项除外)。
  • CS9115可写引用无法返回只读类型的主要构造函数参数。
  • CS9116无法将只读类型的主构造函数参数用作 ref 或 out 值(在该类型的仅限 init 的资源库中或变量初始值设定项除外)。
  • CS9117:不能修改只读类型的主构造函数参数的成员(在该类型的仅限 init 的资源库中或变量初始值设定项除外)。
  • CS9118只读类型的主构造函数参数的成员不能通过可写引用返回。
  • CS9119不能将只读类型的主构造函数参数的成员用作 refout 值(在该类型的仅限 init 的资源库中或变量初始值设定项除外)。
  • CS9120无法按引用返回主构造函数参数。
  • CS9121结构主构造函数参数的类型会导致结构布局中的循环。
  • CS9122意外的参数列表。
  • CS9136无法在实例成员内使用类型的主构造函数参数。

此外,本文还介绍了以下警告:

  • CS0824构造函数“name”标记为外部对象。
  • CS9107参数被捕获到封闭类型的状态,其值也传递给基构造函数。也可以由基类捕获该值。
  • CS9113参数未读。
  • CS9124参数被捕获到封闭类型的状态中,其值还会用于初始化字段、属性或事件。
  • CS9179主构造函数参数被基成员隐藏
  • CS9018在显式赋值之前读取自动实现属性,导致之前隐式赋值为“default”。
  • CS9019在字段被显式分配之前读取,导致字段被隐式分配为“default”。
  • CS9020:在其所有字段被全部分配之前读取“this”对象,这导致对未显式分配的字段进行了默认值的隐式分配。
  • CS9021:在 显式分配自动实现的属性之前,控件将返回到调用方,导致前面的隐式分配为“default”。
  • CS9022在显式分配字段之前,控件将返回到调用方,导致前面的隐式分配为“default”。

静态构造函数

  • CS0132“构造函数”:静态构造函数必须无参数。
  • CS0514静态构造函数不能具有显式的“this”或“base”构造函数调用。
  • CS0515静态构造函数中不允许出现访问修饰符。

静态构造函数初始化类型的静态数据。 有关详细信息,请参阅静态构造函数

若要更正这些错误,请确保静态构造函数声明遵循以下规则:

  • 从静态构造函数声明中删除任何参数,因为静态构造函数必须是无参数的(CS0132)。 如果需要传递初始化值,请考虑使用在静态构造函数运行之前设置的静态字段或属性。
  • 删除静态构造函数中的任何访问修饰符,例如publicprotectedprivateinternal,因为运行时决定静态构造函数的执行时机,而访问修饰符无意义(CS0515)。
  • 从静态构造函数中删除任何 : base(): this() 构造函数初始值设定项调用,因为静态构造函数无法链接到其他构造函数(CS0514)。 如果存在,运行时会自动调用基类静态构造函数。

构造函数声明

  • CS0526接口不能包含构造函数。
  • CS0710静态类不能有实例构造函数。
  • CS8054枚举不能包含显式的无参数构造函数。
  • CS8358无法使用属性构造函数,因为它具有“in”参数。
  • CS8091构造函数不能是外部构造函数,并且具有构造函数初始值设定项。

可以仅在classstruct类型中声明构造函数,包括record classrecord struct类型。 有关详细信息,请参阅 实例构造函数

若要修复这些错误,请尝试以下建议:

将构造函数移动到classstruct类型,因为不能在interfaceenum类型中声明构造函数(CS0526, CS8054)。 接口定义协定,但不提供初始化逻辑,枚举类型在编译时定义其值。

从静态类中删除实例构造函数,因为无法实例化静态类,因此不能有实例构造函数(CS0710)。 如果需要初始化逻辑,请改用静态构造函数。

将参数更改为 in 属性构造函数中的按值传递参数,因为属性构造函数不支持 in 参数修饰符(CS8358)。 运行时使用反射实例化属性,该反射不支持 in 修饰符。

extern构造函数中删除: base(): this()构造函数初始值设定项,因为外部构造函数无法链接到其他构造函数(CS8091)。 外部提供了外部构造函数的实现,因此无法进行构造函数链接。

可以为构造函数声明生成以下警告:

  • CS0824构造函数标记为外部对象。

标记 extern构造函数时,编译器无法验证实现是否存在。 若要禁止显示此警告,请提供非外部实现,或确保外部实现正确链接。

结构类型中的构造函数

  • CS0568结构不能包含显式无参数构造函数。
  • CS0573“字段声明”:结构中不能有实例字段初始值设定项。
  • CS8958无参数结构构造函数必须为“public”。
  • CS8982具有参数列表的“结构”中声明的构造函数必须具有调用主构造函数或显式声明的构造函数的“this”初始值设定项。
  • CS8983具有字段初始值设定项的“结构”必须包含显式声明的构造函数。

结构类型具有构造函数和字段初始化的特定规则。 有关详细信息,请参阅结构类型文章的结构初始化和默认值部分。

若要修复这些错误,请尝试以下建议:

  • 如果遇到 CS0568CS0573,请升级到 C# 10 或更高版本,因为这些错误仅在较旧版本的 C# 中发生。 现代 C# 允许在结构体中使用显式的无参数构造函数和字段初始化器。
  • public 访问修饰符添加到任何无参数结构构造函数,因为无参数结构构造函数必须是公共构造函数,以确保 default 表达式和数组分配可以正确初始化结构实例(CS8958)。
  • : this(...)将初始值设定项添加到具有主构造函数的结构中显式声明的构造函数,因为所有非无参数构造函数都必须链接到主构造函数或其他显式声明的构造函数,以确保一致的初始化(CS8982)。
  • 当结构使用字段初始化器时,声明一个显式构造函数,因为编译器需要显式构造函数来确保字段初始化器被调用(CS8983)。 此构造函数可以是具有空正文的无参数构造函数。

以下这些警告表明在字段或属性被读取之前或者控制返回给调用者之前,字段或属性没有被显式分配:

  • CS9018在显式分配之前读取自动实现的属性,导致前面的隐式分配为“default”。
  • CS9019在显式分配字段之前读取字段,导致前面的隐式分配为“default”。
  • CS9020:在其所有字段被分配之前读取“this”对象,这导致为未显式分配的字段赋予默认值的隐式分配发生在前。
  • CS9021:在 显式分配自动实现的属性之前,控件将返回到调用方,导致前面的隐式分配为“default”。
  • CS9022在显式分配字段之前,控件将返回到调用方,导致前面的隐式分配为“default”。

若要禁止这些警告,请在读取这些字段之前显式分配所有字段和自动实现的属性,或者在从构造函数返回控件之前(CS9018、CS9019CS9020CS9021CS9022)。 读取未分配的成员时,编译器会将default隐式分配给它们,这可能不是想要的行为。

使用 basethis 进行构造函数调用

  • CS0516构造函数无法调用其自身。
  • CS0517“class”没有基类,无法调用基构造函数。
  • CS0522结构无法调用基类构造函数。
  • CS0768构造函数无法通过另一个构造函数自行调用。
  • CS1018应为关键字“this”或“base”。

通过使用构造函数初始值设定项,一个构造函数可以通过使用 : this(): base()调用另一个构造函数。 有关详细信息,请参阅 使用构造函数

若要修复这些错误,请尝试以下建议:

  • 中断任何循环构造函数调用链,因为构造函数不能通过另一个构造函数(CS0516CS0768)直接或间接调用自身。 确保构造函数链接最终以一个不调用同一类型中其他构造函数的构造函数结尾。
  • 删除: base()结构类型的构造函数或System.Object中的构造函数的初始化器,因为这些类型没有基类构造函数可调用(CS0517CS0522)。 结构类型隐式继承自 System.ValueType,但无法显式调用其构造函数。
  • 完成构造函数初始化程序,或者从构造函数声明中删除冒号(:),因为当冒号紧跟在构造函数签名后面时,编译器期望有this()base()CS1018)。 若未打算进行链式调用,则添加适当的构造函数调用或完全删除冒号。

记录和复制构造函数

  • CS8867基类型中找不到可访问的复制构造函数。
  • CS8868记录中的复制构造函数必须调用基的复制构造函数;如果记录继承自对象,则必须调用无参数对象构造函数。
  • CS8878复制构造函数必须是公共的或受保护的,因为该记录未密封。
  • CS8910主构造函数与合成复制构造函数冲突。

在派生记录类型中,显式复制构造函数必须通过使用 : this() 初始化器调用基类型的复制构造函数。 如果记录直接继承自 System.Object,则可以改为调用无参数对象构造函数(CS8868)。

记录 包括编译器合成的 复制构造函数。 可以编写显式复制构造函数,但它必须满足特定要求。 当记录复制构造函数违反以下要求时,编译器将生成错误:

  • 基类型必须具有可访问的复制构造函数。 所有 record 类型都有一个复制构造函数。 确保基类型是一个 record,或向其添加可访问的复制构造函数(CS8867)。
  • 在派生记录类型中,显式复制构造函数必须通过使用: base() 初始化程序调用基类型的复制构造函数。 如果记录直接继承自 System.Object,则可以改为调用无参数对象构造函数(CS8868)。
  • 复制构造函数必须是 publicprotected 除非记录类型为 sealed。 将适当的访问修饰符添加到复制构造函数(CS8878)。
  • 如果显式复制构造函数的签名与合成复制构造函数相同,则会导致定义冲突。 删除显式拷贝构造函数或修改其签名(CS8910)。

主构造函数声明

主构造函数 直接在类型声明中声明参数。 编译器在主构造函数参数被用于成员或字段初始值设定项时,合成一个字段来存储该参数。

构造函数链接

  • CS8861意外的参数列表。
  • CS8862在具有参数列表的类型中声明的构造函数必须具有“this”构造函数初始值设定项。
  • CS9122意外的参数列表。

当类型具有主构造函数时,所有其他显式声明的构造函数都必须使用 : this(...)链接到它。 添加一个 : this(...) 初始值设定项,该初始值设定项将适当的参数传递给主构造函数(CS8862)。

当基类型没有主构造函数时,请从基类型引用中删除参数列表。 仅当Base具有主构造函数(CS8861)时,语法class Derived : Base(args)才有效。 同样,从 interface 声明中删除主构造函数参数列表,因为接口不能有主构造函数(CS9122)。

基构造函数调用中的参数用法

  • CS9105不能在此上下文中使用主构造函数参数。
  • CS9106标识符在此上下文中的类型和参数之间不明确。

如果将主构造函数参数作为主构造函数声明的一部分传递,则只能在基构造函数调用中使用主构造函数参数。 若要修复 CS9105,请将参数用法移动到类型声明的基子句,而不是在显式声明的构造函数调用 : base() 中使用。

如果类型和主构造函数参数共享相同的名称,则引用变得不明确。 若要修复 CS9106,请重命名类型或参数。

类似 Ref 的类型参数

  • CS9108无法使用在匿名方法、lambda 表达式、查询表达式或本地函数中具有类似 ref 类型的参数。
  • CS9109不能在实例成员内使用 refoutin 主构造函数参数。
  • CS9110无法在实例成员中使用具有 ref 类似类型的主构造函数参数。
  • CS9136无法在实例成员内使用类型的主构造函数参数。

若要解决这些错误,

  • ref struct 类型的主构造函数参数在其使用位置上存在限制。 将参数访问移出 lambda 表达式、查询表达式或本地函数(CS9108)。 在不是ref struct的类型中,仅在字段初始值设定项或构造函数正文(而不是实例成员(ref structCS9136)中访问参数。
  • 对于ref struct类型,不能在实例方法或属性访问器中使用主构造函数参数inrefout修饰符。 将参数值复制到构造函数中的字段,并在实例成员中使用该字段(CS9109)。

结构类型限制

  • CS9111结构实例成员内的匿名方法、lambda 表达式、查询表达式和本地函数无法访问主构造函数参数。
  • CS9112匿名方法、lambda 表达式、查询表达式和结构内的本地函数无法访问实例成员内也使用的主构造函数参数。
  • CS9120无法按引用返回主构造函数参数。
  • CS9121类型的结构主构造函数参数导致结构布局中出现循环。

若要解决这些错误,

  • 在结构类型中,无法在 lambda 表达式、查询表达式或实例成员内的本地函数中捕获主构造函数参数。 在使用这些上下文(CS9111CS9112)之前,将参数复制到局部变量或字段。
  • 不能通过结构类型中的引用来返回主要构造函数参数。 将值存储在字段中,并根据需要按引用返回该字段(CS9120)。
  • 确保主构造函数参数的类型不会在结构布局中创建循环。 结构不能直接或间接包含其自己的类型的字段(CS9121)。

只读结构体限制

  • CS9114不能为只读类型的主构造函数参数赋值(在该类型的仅限 init 的资源库中或变量初始值设定项除外)。
  • CS9115可写引用无法返回只读类型的主要构造函数参数。
  • CS9116无法将只读类型的主构造函数参数用作 refout 值(在该类型的仅限 init 的资源库中或变量初始值设定项除外)。
  • CS9117不能修改只读类型的主构造函数参数的成员(在该类型的仅限 init 的资源库中或变量初始值设定项除外)。
  • CS9118只读类型的主构造函数参数的成员不能通过可写引用返回。
  • CS9119不能将只读类型的主构造函数参数的成员用作 refout 值(在该类型的仅限 init 的资源库中或变量初始值设定项除外)。

若要解决这些错误,

  • readonly struct 类型中,不能在仅限于初始化的 setter 或变量初始化之外修改主构造函数的参数及其成员。 将赋值移动到字段初始化器或仅初始化属性的设置器(CS9114, CS9117)。
  • 不能通过类型中的 readonly struct 可写引用返回主要构造函数参数及其成员。 readonly ref 返回,或按值返回(CS9115CS9118)。
  • 不能将主要构造函数的参数及其成员作为refoutreadonly struct类型的参数传递。 请改为按值传递或作为 in 参数传递(CS9116CS9119)。

对捕获参数和被遮蔽参数的警告

  • CS9107参数被捕获到封闭类型的状态,并且其值也传递给基本构造函数。也可以由基类捕获该值。
  • CS9113参数未读。
  • CS9124参数被捕获到封闭类型的状态中,其值也被用于初始化字段、属性或事件。
  • CS9179主构造函数参数由基成员隐藏。

以下警告指示存储或访问主构造函数参数的潜在问题:

  • 如果将参数传递给基构造函数并在派生类型中访问该参数,则可以存储两次参数。 基类中可能有一个副本,另一个副本位于派生类中。 请考虑是否需要两个副本,还是重构代码以避免重复(CS9107)。
  • 如果从未读取它,则不需要主构造函数参数。 从主构造函数声明中删除未使用的参数(CS9113)。
  • 如果两者都在封闭类型中捕获参数,并使用它初始化字段、属性或事件,则可以存储参数两次。 请考虑直接使用捕获的参数,而不是初始化单独的成员(CS9124)。
  • 当两者具有相同名称时,基类型成员会隐藏主构造函数参数。 重命名参数以避免混淆(CS9179)。