From bb227d3032c4c75e9cfab197eba1bb6ba1542d22 Mon Sep 17 00:00:00 2001 From: Bill Wagner Date: Thu, 29 Jan 2026 10:06:02 -0500 Subject: [PATCH 1/6] First set of refactoring --- .openpublishing.redirection.csharp.json | 12 ++ .../compiler-messages/constructor-errors.md | 177 +++++++++++------- .../compiler-messages/cs1018.md | 46 ----- .../feature-version-errors.md | 2 +- .../source-generator-errors.md | 6 +- docs/csharp/language-reference/toc.yml | 16 +- docs/csharp/misc/cs0132.md | 37 ---- docs/csharp/misc/cs0573.md | 43 ----- ...n-t-have-specifics-on-this-csharp-error.md | 5 - 9 files changed, 135 insertions(+), 209 deletions(-) delete mode 100644 docs/csharp/language-reference/compiler-messages/cs1018.md delete mode 100644 docs/csharp/misc/cs0132.md delete mode 100644 docs/csharp/misc/cs0573.md diff --git a/.openpublishing.redirection.csharp.json b/.openpublishing.redirection.csharp.json index bc758c61c017f..3270c3ba6cb05 100644 --- a/.openpublishing.redirection.csharp.json +++ b/.openpublishing.redirection.csharp.json @@ -523,6 +523,10 @@ "source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs1009.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/string-literal" }, + { + "source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs1018.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/constructor-errors#constructor-calls-with-base-and-this" + }, { "source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs1019.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/overload-resolution" @@ -2021,6 +2025,10 @@ "source_path_from_root": "/docs/csharp/misc/cs0515.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/constructor-errors#static-constructors" }, + { + "source_path_from_root": "/docs/csharp/misc/cs0132.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/constructor-errors#static-constructors" + }, { "source_path_from_root": "/docs/csharp/misc/cs0516.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/constructor-errors#constructor-calls-with-base-and-this" @@ -2137,6 +2145,10 @@ "source_path_from_root": "/docs/csharp/misc/cs0568.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/constructor-errors#constructors-in-struct-types" }, + { + "source_path_from_root": "/docs/csharp/misc/cs0573.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/constructor-errors#constructors-in-struct-types" + }, { "source_path_from_root": "/docs/csharp/misc/cs0570.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/constructor-errors#CS0570" diff --git a/docs/csharp/language-reference/compiler-messages/constructor-errors.md b/docs/csharp/language-reference/compiler-messages/constructor-errors.md index 83fddeb272192..8b40f95488ba4 100644 --- a/docs/csharp/language-reference/compiler-messages/constructor-errors.md +++ b/docs/csharp/language-reference/compiler-messages/constructor-errors.md @@ -2,6 +2,7 @@ title: Resolve errors related to constructor declarations description: These compiler errors and warnings indicate violations when declaring constructors in classes or structs, including records. This article provides guidance on resolving those errors. f1_keywords: + - "CS0132" - "CS0514" - "CS0515" - "CS0516" @@ -9,9 +10,11 @@ f1_keywords: - "CS0522" - "CS0526" - "CS0568" + - "CS0573" - "CS0710" - "CS0768" - "CS0824" # WRN_ExternCtorNoImplementation + - "CS1018" # ERR_ThisOrBaseExpected - "CS8054" # ERR_EnumsCantContainDefaultConstructor - "CS8091" # ERR_ExternHasConstructorInitializer - "CS8358" # ERR_AttributeCtorInParameter @@ -24,6 +27,11 @@ f1_keywords: - "CS8958" # ERR_NonPublicParameterlessStructConstructor - "CS8982" # ERR_RecordStructConstructorCallsDefaultConstructor - "CS8983" # ERR_StructHasInitializersAndNoDeclaredConstructor + - "CS9018" # WRN_UseDefViolationPropertySupportedVersion - Auto-implemented property '{0}' is read before being explicitly assigned, causing a preceding implicit assignment of 'default'. + - "CS9019" # WRN_UseDefViolationFieldSupportedVersion - Field '{0}' is read before being explicitly assigned, causing a preceding implicit assignment of 'default'. + - "CS9020" # WRN_UseDefViolationThisSupportedVersion - The 'this' object is read before all of its fields have been assigned, causing preceding implicit assignments of 'default' to non-explicitly assigned fields. + - "CS9021" # WRN_UnassignedThisAutoPropertySupportedVersion - Control is returned to caller before auto-implemented property '{0}' is explicitly assigned, causing a preceding implicit assignment of 'default'. + - "CS9022" # WRN_UnassignedThisSupportedVersion - Control is returned to caller before field '{0}' is explicitly assigned, causing a preceding implicit assignment of 'default'. - "CS9105" # ERR_InvalidPrimaryConstructorParameterReference - Cannot use primary constructor parameter '{0}' in this context. - "CS9106" # ERR_AmbiguousPrimaryConstructorParameterAsColorColorReceiver - Identifier '{0}' is ambiguous between type '{1}' and parameter '{2}' in this context. - "CS9107" # WRN_CapturedPrimaryConstructorParameterPassedToBase - Parameter '{0}' is captured into the state of the enclosing type and its value is also passed to the base constructor. The value might be captured by the base class as well. @@ -46,6 +54,7 @@ f1_keywords: - "CS9136" - "CS9179" helpviewer_keywords: + - "CS0132" - "CS0514" - "CS0515" - "CS0516" @@ -53,9 +62,11 @@ helpviewer_keywords: - "CS0522" - "CS0526" - "CS0568" + - "CS0573" - "CS0710" - "CS0768" - "CS0824" + - "CS1018" - "CS8054" - "CS8091" - "CS8358" @@ -68,6 +79,11 @@ helpviewer_keywords: - "CS8958" - "CS8982" - "CS8983" + - "CS9018" + - "CS9019" + - "CS9020" + - "CS9021" + - "CS9022" - "CS9105" - "CS9106" - "CS9107" @@ -89,7 +105,7 @@ helpviewer_keywords: - "CS9124" - "CS9136" - "CS9179" -ms.date: 11/22/2024 +ms.date: 01/28/2026 --- # Resolve errors and warnings in constructor declarations @@ -98,15 +114,18 @@ This article covers the following compiler errors: +- [**CS0132**](#static-constructors): *'constructor': a static constructor must be parameterless.* - [**CS0514**](#static-constructors): *static constructor cannot have an explicit 'this' or 'base' constructor call.* - [**CS0515**](#static-constructors): *access modifiers are not allowed on static constructors.* - [**CS0516**](#constructor-calls-with-base-and-this): *Constructor 'constructor' can not call itself.* -- [**CS0517**](#constructor-declaration): *'class' has no base class and cannot call a base constructor.* +- [**CS0517**](#constructor-calls-with-base-and-this): *'class' has no base class and cannot call a base constructor.* - [**CS0522**](#constructor-calls-with-base-and-this): *structs cannot call base class constructors.* - [**CS0526**](#constructor-declaration): *Interfaces cannot contain constructors.* - [**CS0568**](#constructors-in-struct-types): *Structs cannot contain explicit parameterless constructors.* +- [**CS0573**](#constructors-in-struct-types): *'field declaration': cannot have instance field initializers in structs.* - [**CS0710**](#constructor-declaration): *Static classes cannot have instance constructors.* - [**CS0768**](#constructor-calls-with-base-and-this): *Constructor cannot call itself through another constructor.* +- [**CS1018**](#constructor-calls-with-base-and-this): *Keyword 'this' or 'base' expected.* - [**CS8054**](#constructor-declaration): *Enums cannot contain explicit parameterless constructors.* - [**CS8091**](#constructor-declaration): *cannot be extern and have a constructor initializer.* - [**CS8861**](#primary-constructor-declaration): *Unexpected argument list.* @@ -144,17 +163,25 @@ In addition, the following warnings are covered in this article: - [**CS9113**](#primary-constructor-declaration): *Parameter is unread.* - [**CS9124**](#primary-constructor-declaration): *Parameter is captured into the state of the enclosing type and its value is also used to initialize a field, property, or event.* - [**CS9179**](#primary-constructor-declaration): *Primary constructor parameter is shadowed by a member from base* +- [**CS9018**](#constructors-in-struct-types): *Auto-implemented property is read before being explicitly assigned, causing a preceding implicit assignment of 'default'.* +- [**CS9019**](#constructors-in-struct-types): *Field is read before being explicitly assigned, causing a preceding implicit assignment of 'default'.* +- [**CS9020**](#constructors-in-struct-types): *The 'this' object is read before all of its fields have been assigned, causing preceding implicit assignments of 'default' to non-explicitly assigned fields.* +- [**CS9021**](#constructors-in-struct-types): *Control is returned to caller before auto-implemented property is explicitly assigned, causing a preceding implicit assignment of 'default'.* +- [**CS9022**](#constructors-in-struct-types): *Control is returned to caller before field is explicitly assigned, causing a preceding implicit assignment of 'default'.* ## Static constructors +- **CS0132**: *'constructor': a static constructor must be parameterless.* - **CS0514**: *Static constructor cannot have an explicit 'this' or 'base' constructor call.* - **CS0515**: *Access modifiers are not allowed on static constructors.* -You can write at most one static constructor for a type. The declaration of a static constructor must obey the following rules: +Static constructors initialize static data for a type. For more information, see [Static Constructors](../../programming-guide/classes-and-structs/static-constructors.md). -- The static constructor has the `static` modifier, but no other modifiers, such as `public`, `protected`, `private`, or `internal`. -- The static constructor must be a parameterless constructor. -- The static constructor must not call `base()` or `this()`. If the base class includes a static constructor, the runtime calls it automatically. +To correct these errors, ensure your static constructor declaration follows these rules: + +- Remove any parameters from the static constructor declaration, because a static constructor must be parameterless (**CS0132**). If you need to pass initialization values, consider using static fields or properties that are set before the static constructor runs. +- Remove any access modifiers such as `public`, `protected`, `private`, or `internal` from the static constructor, because the runtime controls when the static constructor executes and access modifiers aren't meaningful (**CS0515**). +- Remove any `: base()` or `: this()` constructor initializer calls from the static constructor, because static constructors can't chain to other constructors (**CS0514**). The runtime automatically invokes the base class static constructor if one exists. ## Constructor declaration @@ -164,60 +191,66 @@ You can write at most one static constructor for a type. The declaration of a st - **CS8358**: *Cannot use attribute constructor because it has 'in' parameters.* - **CS8091**: *A constructor cannot be extern and have a constructor initializer.* -Constructors are allowed only in `class` and `struct` types, including `record class` and `record struct` types. You can't define them in `enum` or `interface` types. Furthermore, [attribute](../attributes/general.md) class types can't declare `in` parameters. Instead, pass parameters by value. +Constructors are allowed only in `class` and `struct` types, including `record class` and `record struct` types. For more information, see [Instance Constructors](../../programming-guide/classes-and-structs/instance-constructors.md). + +To correct these errors, consider the following guidance: + +Move the constructor to a `class` or `struct` type, because constructors can't be declared in `interface` or `enum` types (**CS0526**, **CS8054**). Interfaces define contracts but don't provide initialization logic, and enum types have their values defined at compile time. + +Remove instance constructors from static classes, because static classes can't be instantiated and therefore can't have instance constructors (**CS0710**). If you need initialization logic, use a static constructor instead. -You can declare `extern` constructors, however you can't use `base()` or `this()` constructor calls to call another constructor from a constructor declared `extern`. +Change `in` parameters to pass-by-value parameters in attribute constructors, because attribute constructors don't support `in` parameter modifiers (**CS8358**). Attributes are instantiated by the runtime using reflection, which doesn't support the `in` modifier. -In addition, the following warnings can be generated for constructor declarations: +Remove the `: base()` or `: this()` constructor initializer from an `extern` constructor, because extern constructors can't chain to other constructors (**CS8091**). The implementation of an extern constructor is provided externally, so constructor chaining isn't possible. + +The following warning can be generated for constructor declarations: - **CS0824**: *Constructor is marked external.* -When a constructor is marked `extern`, the compiler can't guarantee the constructor exists. Therefore, the compiler generates this warning. +When a constructor is marked `extern`, the compiler can't verify that an implementation exists. To suppress this warning, either provide a non-extern implementation or ensure the external implementation is correctly linked. ## Constructors in struct types - **CS0568**: *Structs cannot contain explicit parameterless constructors.* +- **CS0573**: *'field declaration': cannot have instance field initializers in structs.* - **CS8958**: *The parameterless struct constructor must be 'public'.* - **CS8982**: *A constructor declared in a 'struct' with parameter list must have a 'this' initializer that calls the primary constructor or an explicitly declared constructor.* - **CS8983**: *A 'struct' with field initializers must include an explicitly declared constructor.* -Recent features in C# remove earlier restrictions to `struct` types. **CS0568** is generated when you declare a parameterless instance constructor in older versions of C#. You can declare an explicit parameterless instance constructor in newer versions of C#. That explicit parameterless constructor must be `public`. If your `struct` declares any [field initializers](../../programming-guide/classes-and-structs/fields.md), you must also declare an explicit instance constructor. This constructor can be a parameterless constructor with an empty body. +Struct types have specific rules for constructors and field initialization. For more information, see the [Struct initialization and default values](../builtin-types/struct.md#struct-initialization-and-default-values) section of the [Structure types](../builtin-types/struct.md) article. -When a `struct` type declares a primary constructor, including `record struct` types, all other instance constructors except a parameterless constructor must call the primary constructor or another explicitly declared constructor using `this()`. +To correct these errors, consider the following guidance: -## Constructor calls with `base` and `this` +- Upgrade to C# 10 or later if you encounter **CS0568** or **CS0573**, because these errors are generated only in older versions of C#. Modern C# allows explicit parameterless constructors and field initializers in structs. +- Add the `public` access modifier to any parameterless struct constructor, because parameterless struct constructors must be public to ensure the `default` expression and array allocation can properly initialize struct instances (**CS8958**). +- Add a `: this(...)` initializer to explicitly declared constructors in a struct that has a primary constructor, because all non-parameterless constructors must chain to the primary constructor or another explicitly declared constructor to ensure consistent initialization (**CS8982**). +- Declare an explicit constructor when your struct uses field initializers, because the compiler requires an explicit constructor to ensure field initializers are invoked (**CS8983**). This constructor can be a parameterless constructor with an empty body. -- **CS0516**: *Constructor can not call itself.* -- **CS0517**: *Class has no base class and cannot call a base constructor.* -- **CS0522**: *Structs cannot call base class constructors.* -- **CS0768**: *Constructor cannot call itself through another constructor.* +The following warnings indicate that a field or property isn't explicitly assigned before being read or before control returns to the caller: -You can use `base()` and `this()` to have one constructor call another in the same type or the base type. Calling constructors can minimize duplicated constructor logic. You must follow these rules when calling another constructor using `this()` or `base()`: +- **CS9018**: *Auto-implemented property is read before being explicitly assigned, causing a preceding implicit assignment of 'default'.* +- **CS9019**: *Field is read before being explicitly assigned, causing a preceding implicit assignment of 'default'.* +- **CS9020**: *The 'this' object is read before all of its fields have been assigned, causing preceding implicit assignments of 'default' to non-explicitly assigned fields.* +- **CS9021**: *Control is returned to caller before auto-implemented property is explicitly assigned, causing a preceding implicit assignment of 'default'.* +- **CS9022**: *Control is returned to caller before field is explicitly assigned, causing a preceding implicit assignment of 'default'.* -- A constructor can't call itself either directly or indirectly through another constructor. For example, the following code is illegal: +To silence these warnings, explicitly assign all fields and auto-implemented properties before reading them or before control returns from the constructor (**CS9018**, **CS9019**, **CS9020**, **CS9021**, **CS9022**). When unassigned members are read, the compiler implicitly assigns `default` to them, which may not be the intended behavior. - ```csharp - public class C - { - public C() : this() // Error! - { - } - } +## Constructor calls with `base` and `this` - public class C2 - { - public class C2() : this(10) {} +- **CS0516**: *Constructor can not call itself.* +- **CS0517**: *'class' has no base class and cannot call a base constructor.* +- **CS0522**: *Structs cannot call base class constructors.* +- **CS0768**: *Constructor cannot call itself through another constructor.* +- **CS1018**: *Keyword 'this' or 'base' expected.* - public class C2(int capacity) : this() - { - _capacity = capacity; - } +Constructor initializers allow one constructor to call another using `: this()` or `: base()`. For more information, see [Using Constructors](../../programming-guide/classes-and-structs/using-constructors.md). - private int _capacity; - } - `` +To correct these errors, consider the following guidance: -- Struct types can't call `base()`. Neither can . +- Break any circular constructor call chains, because a constructor can't call itself either directly or indirectly through another constructor (**CS0516**, **CS0768**). Ensure that constructor chaining eventually terminates at a constructor that doesn't call another constructor in the same type. +- Remove the `: base()` initializer from constructors in struct types or from constructors in , because these types have no base class constructor to call (**CS0517**, **CS0522**). Struct types implicitly inherit from , but you can't explicitly call its constructor. +- Complete the constructor initializer or remove the colon (`:`) from the constructor declaration, because when a colon follows a constructor signature, the compiler expects either `this()` or `base()` (**CS1018**). Either add the appropriate constructor call or remove the colon entirely if no chaining is intended. ## Records and copy constructors @@ -225,16 +258,18 @@ You can use `base()` and `this()` to have one constructor call another in the sa - **CS8868**: *A copy constructor in a record must call a copy constructor of the base, or a parameterless object constructor if the record inherits from object.* - **CS8878**: *A copy constructor must be public or protected because the record is not sealed.* - **CS8910**: *The primary constructor conflicts with the synthesized copy constructor.* +In a derived record type, your explicit copy constructor must call the base type's copy constructor using the `: this()` initializer. If the record directly inherits from , it can call the parameterless object constructor instead (**CS8868**). -Adding the `record` modifier to a `struct` or `class` type creates a [record](../builtin-types/record.md). Records include a compiler-synthesized [copy constructor](../builtin-types/record.md#nondestructive-mutation). You can write an explicit copy constructor yourself, but it must adhere to the following rules: +[Records](../builtin-types/record.md) include a compiler-synthesized [copy constructor](../builtin-types/record.md#nondestructive-mutation). You can write an explicit copy constructor, but it must meet specific requirements. The compiler issues errors when record copy constructors violate these requirements: -- Copy constructors must be `public` or `protected` unless the type is [`sealed`](../keywords/sealed.md). -- Copy constructors must call the `base()` copy constructor unless the base class is . -- Furthermore, the base type must have a copy constructor. `record` types always have a copy constructor. +- The base type must have an accessible copy constructor. All `record` types have a copy constructor. Ensure the base type is a `record`, or add an accessible copy constructor to it (**CS8867**). +- In a derived record type, your explicit copy constructor must call the base type's copy constructor using the `: this()` initializer. If the record directly inherits from , it can call the parameterless object constructor instead (**CS8868**). +- Copy constructors must be `public` or `protected` unless the record type is [`sealed`](../keywords/sealed.md). Add the appropriate access modifier to the copy constructor (**CS8878**). +- If your explicit copy constructor has the same signature as the synthesized copy constructor, the definitions conflict. Remove your explicit copy constructor or modify its signature (**CS8910**). ## Primary constructor declaration -The compiler emits the following errors when a primary constructor violates one or more rules on primary constructors for classes and structs: +[Primary constructors](../../programming-guide/classes-and-structs/instance-constructors.md#primary-constructors) declare parameters directly in the type declaration. The compiler synthesizes a field to store a primary constructor parameter when it's used in members or field initializers. The compiler issues errors when code violates rules for primary constructor usage. - **CS8861**: *Unexpected argument list.* - **CS8862**: *A constructor declared in a type with parameter list must have 'this' constructor initializer.* @@ -257,34 +292,50 @@ The compiler emits the following errors when a primary constructor violates one - **CS9124**: *Parameter is captured into the state of the enclosing type and its value is also used to initialize a field, property, or event.* - **CS9136**: *Cannot use primary constructor parameter of type inside an instance member.* -When using a primary constructor in a class or struct, every explicitly declared constructor must call the primary constructor using `: this(...)` with an appropriate argument list. This ensures that the primary constructor is always invoked. For more information on primary constructors, see the article on [instance constructors](../../programming-guide/classes-and-structs/instance-constructors.md#primary-constructors) in the programming guide. +[Primary constructors](../../programming-guide/classes-and-structs/instance-constructors.md#primary-constructors) declare parameters directly in the type declaration. The compiler synthesizes a field to store a primary constructor parameter when it's used in members or field initializers. The compiler issues errors when code violates rules for primary constructor usage. + +### Constructor chaining + +When a type has a primary constructor, all other explicitly declared constructors must chain to it using `: this(...)`. Add a `: this(...)` initializer that passes appropriate arguments to the primary constructor (**CS8862**). + +Remove a parameter list from the base type reference when the base type doesn't have a primary constructor. The syntax `class Derived : Base(args)` is only valid when `Base` has a primary constructor (**CS8861**). Similarly, remove a primary constructor parameter list from an `interface` declaration, because interfaces can't have primary constructors (**CS9122**). + +### Parameter usage in base constructor calls + +Primary constructor parameters can only be used in the base constructor call when passed as part of the primary constructor declaration. Move the parameter usage to the type declaration's base clause rather than using it in an explicitly declared constructor's `: base()` call (**CS9105**). + +When a type and a primary constructor parameter have the same name, the reference is ambiguous. Rename either the type or the parameter to resolve the ambiguity (**CS9106**). + +### Ref-like type parameters + +Primary constructor parameters of `ref struct` type have restrictions on where they can be used. Move the parameter access out of lambda expressions, query expressions, or local functions (**CS9108**). In types that aren't `ref struct`, access `ref struct` parameters only in field initializers or the constructor body, not in instance members (**CS9110**, **CS9136**). + +For `ref struct` types, primary constructor parameters with `in`, `ref`, or `out` modifiers can't be used in instance methods or property accessors. Copy the parameter value to a field in the constructor and use that field in instance members instead (**CS9109**). + +### Struct type restrictions + +In struct types, primary constructor parameters can't be captured in lambda expressions, query expressions, or local functions inside instance members. Copy the parameter to a local variable or field before using it in these contexts (**CS9111**, **CS9112**). + +Primary constructor parameters in struct types can't be returned by reference. Store the value in a field and return that field by reference if needed (**CS9120**). + +Ensure that a primary constructor parameter's type doesn't create a cycle in the struct layout. A struct can't contain a field of its own type either directly or indirectly (**CS9121**). -Primary constructor parameters are in scope in the body of that type. The compiler can synthesize a field that stores the parameter for use in members or in field initializers. Because a primary constructor parameter may be copied to a field, the following restrictions apply: +### Readonly struct restrictions -- Primary constructors can be declared on `struct` and `class` types, but not on `interface` types. -- Primary constructor parameters can't be used in a `base()` constructor call except as part of the primary constructor. -- Primary constructor parameters of `ref struct` type can't be accessed in lambda expressions, query expressions, or local functions. -- If the type isn't a `ref struct`, `ref struct` parameters can't be accessed in instance members. -- In a `ref struct` type, primary constructor parameters with the `in`, `ref`, or `out` modifiers can't be used in any instance methods or property accessors. +In `readonly struct` types, primary constructor parameters and their members can't be modified outside of init-only setters or variable initializers. Move assignments to field initializers or init-only property setters (**CS9114**, **CS9117**). -Struct types have the following extra restrictions on primary constructor parameters: +Primary constructor parameters and their members in `readonly struct` types can't be returned by writable reference. Return by `readonly ref` or by value instead (**CS9115**, **CS9118**). -- Primary constructor parameters can't be captured in lambda expressions, query expressions, or local functions. -- Primary constructor parameters can't be returned by reference (`ref` return or `readonly ref` return). +Primary constructor parameters and their members in `readonly struct` types can't be passed as `ref` or `out` arguments. Pass them by value or as `in` arguments instead (**CS9116**, **CS9119**). -Readonly only struct types have the following extra restrictions on primary constructor parameters: +### Warnings for captured and shadowed parameters -- Primary constructor parameters and their members can't be reassigned in a `readonly` struct. -- Primary constructor parameters and their members can't be `ref` returned in a `readonly` struct. -- Primary constructor parameters and their members can't be `ref` or `out` arguments to any method. +The following warnings indicate potential issues with how primary constructor parameters are stored or accessed: -In all these cases, the restrictions on primary constructor parameters are consistent with restrictions on data fields in those types. The restrictions are because a primary constructor parameter may be transformed into a synthesized field in the type. Therefore primary constructor parameters must follow the rules that apply to that synthesized field. +A parameter that's both passed to the base constructor and accessed in the derived type may be stored twice—once in the base class and once in the derived class. Consider whether both copies are necessary, or restructure your code to avoid the duplication (**CS9107**). -A derived primary constructor calls the base primary constructor by supplying the parameters to the base constructor. You must use the parameter names from the derived constructor declaration. +A primary constructor parameter that's never read isn't needed. Remove unused parameters from the primary constructor declaration (**CS9113**). -The warnings provide guidance on captured or shadowed primary constructor parameters. +A parameter that's both captured by the enclosing type and used to initialize a field, property, or event may be stored twice. Consider using the captured parameter directly instead of initializing a separate member (**CS9124**). -- **CS9107**: *Parameter is captured into the state of the enclosing type and its value is also passed to the base constructor. The value might be captured by the base class as well.* This warning indicates that your code may be allocated two copies of a primary constructor parameter. Because the parameter is passed to the base class, the base class likely uses it. Because the derived class accesses it, it may have a second copy of the same parameter. That extra storage may not be intended. -- **CS9113**: *Parameter is unread.* This warning indicates that your class never references the primary constructor, even to pass it to the base primary constructor. It likely isn't needed. -- **CS9124**: *Parameter is captured into the state of the enclosing type and its value is also used to initialize a field, property, or event.* This warning indicates that the constructor parameter of a nested type is also captured by the enclosing type. The parameter is likely stored twice. -- **CS9179**: *Primary constructor parameter is shadowed by a member from base* +When a base type member has the same name as a primary constructor parameter, the base member shadows the parameter. Rename the parameter to avoid confusion (**CS9179**). diff --git a/docs/csharp/language-reference/compiler-messages/cs1018.md b/docs/csharp/language-reference/compiler-messages/cs1018.md deleted file mode 100644 index 84d6d6f1894c7..0000000000000 --- a/docs/csharp/language-reference/compiler-messages/cs1018.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -description: "Compiler Error CS1018" -title: "Compiler Error CS1018" -ms.date: 07/20/2015 -f1_keywords: - - "CS1018" -helpviewer_keywords: - - "CS1018" -ms.assetid: f6dc7f6a-57fd-4c9e-8699-add3218af983 ---- -# Compiler Error CS1018 - -Keyword 'this' or 'base' expected - - The compiler encountered an incomplete constructor declaration. - -## Example - - The following example generates CS1018, and suggests several ways to resolve the error: - -```csharp -// CS1018.cs -public class C -{ -} - -public class a : C -{ - public a(int i) - { - } - - public a () : // CS1018 - // possible resolutions: - // public a () resolves by removing the colon - // public a () : base() calls C's parameterless constructor - // public a () : this(1) calls the assignment constructor of class a - { - } - - public static int Main() - { - return 1; - } -} -``` diff --git a/docs/csharp/language-reference/compiler-messages/feature-version-errors.md b/docs/csharp/language-reference/compiler-messages/feature-version-errors.md index 8e24424487f6a..81f1f9616f7d2 100644 --- a/docs/csharp/language-reference/compiler-messages/feature-version-errors.md +++ b/docs/csharp/language-reference/compiler-messages/feature-version-errors.md @@ -152,7 +152,7 @@ That's be design. The text closely matches the text of the compiler error / warn - **CS8929**: *Method cannot implement interface member in type because the target runtime doesn't support static abstract members in interfaces.* - **CS8957**: *Conditional expression is not valid in language version because a common type was not found between types.* - **CS8967**: *Newlines inside a non-verbatim interpolated string are not supported in C#* -- **CS9041**: *Requires compiler feature, which is not supported by this version of the C# compiler.* +- **CS9041**: *Requires compiler feature that is not supported by this version of the C# compiler.* - **CS9014**: *Error: Use of possibly unassigned property. Upgrade to auto-default the property.* - **CS9015**: *Error: Use of possibly unassigned field. Upgrade to auto-default the field.* - **CS9016**: *Warning: Use of possibly unassigned property. Upgrade to auto-default the property.* diff --git a/docs/csharp/language-reference/compiler-messages/source-generator-errors.md b/docs/csharp/language-reference/compiler-messages/source-generator-errors.md index 465aa81bef996..5d82a64d12907 100644 --- a/docs/csharp/language-reference/compiler-messages/source-generator-errors.md +++ b/docs/csharp/language-reference/compiler-messages/source-generator-errors.md @@ -132,7 +132,7 @@ These errors and warnings follow these themes: - **CS9137**: *The 'interceptors' experimental feature is not enabled. Add `InterceptorsPreview` to your project.* -To use interceptors, add the `InterceptorsPreview` element to your project file within a `` section (**CS9137**), because interceptors are an experimental feature that isn't enabled by default. This explicit opt-in is required because interceptors are subject to breaking changes or removal in future releases, and the compiler needs confirmation that you understand the risks before allowing their use. For more information about interceptors and their capabilities, see [Interceptors](../../whats-new/csharp-12.md#interceptors) in the C# 12 features documentation. +To use interceptors, add the `InterceptorsPreview` element to your project file within a `` section (**CS9137**), because interceptors are an experimental feature that isn't enabled by default. This explicit opt-in is required because the interceptors feature is subject to breaking changes or removal in future releases, and the compiler needs confirmation that you understand the risks before allowing its use. For more information about interceptors and their capabilities, see [Interceptors](../../whats-new/csharp-12.md#interceptors) in the C# 12 features documentation. ## Signature mismatch @@ -229,5 +229,5 @@ The following warnings indicate issues with analyzer or source generator assembl These warnings occur when there are compatibility issues with analyzer assemblies: -- **CS9057** is generated when an analyzer assembly references a version of the Roslyn compiler that is newer than the one currently running. This prevents the analyzer from loading because it may depend on APIs or behaviors not available in the current compiler version. To resolve this, either upgrade your compiler/SDK to match the analyzer's requirements or use a version of the analyzer compatible with your current compiler version. -- **CS9067** warns when the same analyzer assembly is referenced multiple times in your project. This typically happens when an analyzer is included through multiple paths or package references. While not an error, duplicate references can impact build performance and may cause unexpected behavior. Remove the duplicate references to resolve this warning. +- **CS9057** is generated when an analyzer assembly references a version of the Roslyn compiler that is newer than the one currently running. This prevents the analyzer from loading because it might depend on APIs or behaviors not available in the current compiler version. To resolve this, either upgrade your compiler/SDK to match the analyzer's requirements or use a version of the analyzer compatible with your current compiler version. +- **CS9067** warns when the same analyzer assembly is referenced multiple times in your project. This typically happens when an analyzer is included through multiple paths or package references. While not an error, duplicate references can impact build performance and might cause unexpected behavior. Remove the duplicate references to resolve this warning. diff --git a/docs/csharp/language-reference/toc.yml b/docs/csharp/language-reference/toc.yml index 7db7bac4fec10..48b8779ca1ef7 100644 --- a/docs/csharp/language-reference/toc.yml +++ b/docs/csharp/language-reference/toc.yml @@ -490,11 +490,11 @@ items: href: ./compiler-messages/constructor-errors.md displayName: > Primary constructors, - CS0514, CS0515, CS0516, CS0517, CS0522, CS0526, CS0568, CS0710, CS0768, CS0824, - CS8054, CS8091, CS8358, CS8862, CS8867, CS8868, CS8878, CS8910, CS8958, CS8982, - CS8983, CS9105, CS9106, CS9107, CS9108, CS9109, CS9110, CS9111, CS9112, CS9113, - CS9114, CS9115, CS9116, CS9117, CS9118, CS9119, CS9120, CS9121, CS9122, CS9124, - CS9136, CS9179 + CS0132, CS0514, CS0515, CS0516, CS0517, CS0522, CS0526, CS0568, CS0573, CS0710, + CS0768, CS0824, CS1018, CS8054, CS8091, CS8358, CS8862, CS8867, CS8868, CS8878, + CS8910, CS8958, CS8982, CS8983, CS9018, CS9019, CS9020, CS9021, CS9022, CS9105, + CS9106, CS9107, CS9108, CS9109, CS9110, CS9111, CS9112, CS9113, CS9114, CS9115, + CS9116, CS9117, CS9118, CS9119, CS9120, CS9121, CS9122, CS9124, CS9136, CS9179 - name: Property declarations href: ./compiler-messages/property-declaration-errors.md displayName: > @@ -843,8 +843,6 @@ items: href: ../misc/cs0128.md - name: CS0131 href: ../misc/cs0131.md - - name: CS0132 - href: ../misc/cs0132.md - name: CS0133 href: ../misc/cs0133.md - name: CS0134 @@ -1131,8 +1129,6 @@ items: href: ./compiler-messages/property-declaration-errors.md - name: CS0572 href: ../misc/cs0572.md - - name: CS0573 - href: ../misc/cs0573.md - name: CS0574 href: ../misc/cs0574.md - name: CS0575 @@ -1345,8 +1341,6 @@ items: href: ../misc/cs1015.md - name: CS1017 href: ../misc/cs1017.md - - name: CS1018 - href: ./compiler-messages/cs1018.md - name: CS1021 href: ../misc/cs1021.md - name: CS1022 diff --git a/docs/csharp/misc/cs0132.md b/docs/csharp/misc/cs0132.md deleted file mode 100644 index 1aed19ee48f1b..0000000000000 --- a/docs/csharp/misc/cs0132.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -description: "Compiler Error CS0132" -title: "Compiler Error CS0132" -ms.date: 07/20/2015 -f1_keywords: - - "CS0132" -helpviewer_keywords: - - "CS0132" -ms.assetid: e8ad1281-2912-4b6a-b2af-a319a23ddd16 ---- -# Compiler Error CS0132 - -'constructor' : a static constructor must be parameterless - - A [static](../language-reference/keywords/static.md) constructor cannot be declared with one or more parameters. For more information, see [Static Constructors](../programming-guide/classes-and-structs/static-constructors.md). - - The following sample generates CS0132: - -```csharp -// CS0132.cs -namespace MyNamespace -{ - public class MyClass - { - public MyClass(int i) - { - } - } - - public class MyClass2 : MyClass - { - static MyClass2(int i) // CS0132 - { - } - } -} -``` diff --git a/docs/csharp/misc/cs0573.md b/docs/csharp/misc/cs0573.md deleted file mode 100644 index 6d1198ee61f1d..0000000000000 --- a/docs/csharp/misc/cs0573.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -description: "Compiler Error CS0573" -title: "Compiler Error CS0573" -ms.date: 11/22/2024 -f1_keywords: - - "CS0573" -helpviewer_keywords: - - "CS0573" -ms.assetid: 10ef9625-44f1-4936-ada3-56938357aa01 ---- -# Compiler Error CS0573 - -'field declaration' : cannot have instance field initializers in structs - - You can't initialize an instance field of a [struct](../language-reference/builtin-types/struct.md). Fields of value types will be initialized to their default values, and reference-type fields will be initialized to `null`. - -> [!NOTE] -> You can initialize a struct's instance field or property at its declaration. For more information, see the [Struct initialization and default values](../language-reference/builtin-types/struct.md#struct-initialization-and-default-values) section of the [Structure types](../language-reference/builtin-types/struct.md) article. - -## Example - - The following sample generates CS0573: - -```csharp -// CS0573.cs -namespace x -{ - public class clx - { - public static void Main() - { - } - } - - public struct cly - { - clx a = new clx(); // CS0573 - // clx a; // OK - int i = 7; // CS0573 - // int i; // OK - } -} -``` diff --git a/docs/csharp/misc/sorry-we-don-t-have-specifics-on-this-csharp-error.md b/docs/csharp/misc/sorry-we-don-t-have-specifics-on-this-csharp-error.md index 418261182c03b..8417d6c3831b6 100644 --- a/docs/csharp/misc/sorry-we-don-t-have-specifics-on-this-csharp-error.md +++ b/docs/csharp/misc/sorry-we-don-t-have-specifics-on-this-csharp-error.md @@ -446,11 +446,6 @@ f1_keywords: - "CS8989" - "CS9011" - "CS9012" - - "CS9018" - - "CS9019" - - "CS9020" - - "CS9021" - - "CS9022" - "CS9044" - "CS9046" - "CS9064" From 793bbae12b452dcf16a66593a87beca28e1a4fec Mon Sep 17 00:00:00 2001 From: Bill Wagner Date: Thu, 29 Jan 2026 10:10:29 -0500 Subject: [PATCH 2/6] 2nd pass refactor --- .../compiler-messages/constructor-errors.md | 79 ++++++++++--------- 1 file changed, 42 insertions(+), 37 deletions(-) diff --git a/docs/csharp/language-reference/compiler-messages/constructor-errors.md b/docs/csharp/language-reference/compiler-messages/constructor-errors.md index 8b40f95488ba4..9209b07a60291 100644 --- a/docs/csharp/language-reference/compiler-messages/constructor-errors.md +++ b/docs/csharp/language-reference/compiler-messages/constructor-errors.md @@ -269,32 +269,13 @@ In a derived record type, your explicit copy constructor must call the base type ## Primary constructor declaration -[Primary constructors](../../programming-guide/classes-and-structs/instance-constructors.md#primary-constructors) declare parameters directly in the type declaration. The compiler synthesizes a field to store a primary constructor parameter when it's used in members or field initializers. The compiler issues errors when code violates rules for primary constructor usage. +[Primary constructors](../../programming-guide/classes-and-structs/instance-constructors.md#primary-constructors) declare parameters directly in the type declaration. The compiler synthesizes a field to store a primary constructor parameter when it's used in members or field initializers. + +### Constructor chaining - **CS8861**: *Unexpected argument list.* - **CS8862**: *A constructor declared in a type with parameter list must have 'this' constructor initializer.* -- **CS9105**: *Cannot use primary constructor parameter in this context.* -- **CS9106**: *Identifier is ambiguous between type and parameter in this context.* -- **CS9108**: *Cannot use parameter that has ref-like type inside an anonymous method, lambda expression, query expression, or local function.* -- **CS9109**: *Cannot use `ref`, `out`, or `in` primary constructor parameter inside an instance member.* -- **CS9110**: *Cannot use primary constructor parameter that has ref-like type inside an instance member.* -- **CS9111**: *Anonymous methods, lambda expressions, query expressions, and local functions inside an instance member of a struct cannot access primary constructor parameter.* -- **CS9112**: *Anonymous methods, lambda expressions, query expressions, and local functions inside a struct cannot access primary constructor parameter also used inside an instance member.* -- **CS9114**: *A primary constructor parameter of a readonly type cannot be assigned to (except in init-only setter of the type or a variable initializer).* -- **CS9115**: *A primary constructor parameter of a readonly type cannot be returned by writable reference.* -- **CS9116**: *A primary constructor parameter of a readonly type cannot be used as a `ref` or `out` value (except in init-only setter of the type or a variable initializer).* -- **CS9117**: *Members of primary constructor parameter of a readonly type cannot be modified (except in init-only setter of the type or a variable initializer).* -- **CS9118**: *Members of primary constructor parameter of a readonly type cannot be returned by writable reference.* -- **CS9119**: *Members of primary constructor parameter of a readonly type cannot be used as a `ref` or `out` value (except in init-only setter of the type or a variable initializer).* -- **CS9120**: *Cannot return primary constructor parameter by reference.* -- **CS9121**: *Struct primary constructor parameter of type causes a cycle in the struct layout.* - **CS9122**: *Unexpected parameter list.* -- **CS9124**: *Parameter is captured into the state of the enclosing type and its value is also used to initialize a field, property, or event.* -- **CS9136**: *Cannot use primary constructor parameter of type inside an instance member.* - -[Primary constructors](../../programming-guide/classes-and-structs/instance-constructors.md#primary-constructors) declare parameters directly in the type declaration. The compiler synthesizes a field to store a primary constructor parameter when it's used in members or field initializers. The compiler issues errors when code violates rules for primary constructor usage. - -### Constructor chaining When a type has a primary constructor, all other explicitly declared constructors must chain to it using `: this(...)`. Add a `: this(...)` initializer that passes appropriate arguments to the primary constructor (**CS8862**). @@ -302,40 +283,64 @@ Remove a parameter list from the base type reference when the base type doesn't ### Parameter usage in base constructor calls +- **CS9105**: *Cannot use primary constructor parameter in this context.* +- **CS9106**: *Identifier is ambiguous between type and parameter in this context.* + Primary constructor parameters can only be used in the base constructor call when passed as part of the primary constructor declaration. Move the parameter usage to the type declaration's base clause rather than using it in an explicitly declared constructor's `: base()` call (**CS9105**). When a type and a primary constructor parameter have the same name, the reference is ambiguous. Rename either the type or the parameter to resolve the ambiguity (**CS9106**). ### Ref-like type parameters -Primary constructor parameters of `ref struct` type have restrictions on where they can be used. Move the parameter access out of lambda expressions, query expressions, or local functions (**CS9108**). In types that aren't `ref struct`, access `ref struct` parameters only in field initializers or the constructor body, not in instance members (**CS9110**, **CS9136**). +- **CS9108**: *Cannot use parameter that has ref-like type inside an anonymous method, lambda expression, query expression, or local function.* +- **CS9109**: *Cannot use `ref`, `out`, or `in` primary constructor parameter inside an instance member.* +- **CS9110**: *Cannot use primary constructor parameter that has ref-like type inside an instance member.* +- **CS9136**: *Cannot use primary constructor parameter of type inside an instance member.* -For `ref struct` types, primary constructor parameters with `in`, `ref`, or `out` modifiers can't be used in instance methods or property accessors. Copy the parameter value to a field in the constructor and use that field in instance members instead (**CS9109**). +To address these errors: + +- Primary constructor parameters of `ref struct` type have restrictions on where they can be used. Move the parameter access out of lambda expressions, query expressions, or local functions (**CS9108**). In types that aren't `ref struct`, access `ref struct` parameters only in field initializers or the constructor body, not in instance members (**CS9110**, **CS9136**). +- For `ref struct` types, primary constructor parameters with `in`, `ref`, or `out` modifiers can't be used in instance methods or property accessors. Copy the parameter value to a field in the constructor and use that field in instance members instead (**CS9109**). ### Struct type restrictions -In struct types, primary constructor parameters can't be captured in lambda expressions, query expressions, or local functions inside instance members. Copy the parameter to a local variable or field before using it in these contexts (**CS9111**, **CS9112**). +- **CS9111**: *Anonymous methods, lambda expressions, query expressions, and local functions inside an instance member of a struct cannot access primary constructor parameter.* +- **CS9112**: *Anonymous methods, lambda expressions, query expressions, and local functions inside a struct cannot access primary constructor parameter also used inside an instance member.* +- **CS9120**: *Cannot return primary constructor parameter by reference.* +- **CS9121**: *Struct primary constructor parameter of type causes a cycle in the struct layout.* -Primary constructor parameters in struct types can't be returned by reference. Store the value in a field and return that field by reference if needed (**CS9120**). +To address these errors: -Ensure that a primary constructor parameter's type doesn't create a cycle in the struct layout. A struct can't contain a field of its own type either directly or indirectly (**CS9121**). +- In struct types, primary constructor parameters can't be captured in lambda expressions, query expressions, or local functions inside instance members. Copy the parameter to a local variable or field before using it in these contexts (**CS9111**, **CS9112**). +- Primary constructor parameters in struct types can't be returned by reference. Store the value in a field and return that field by reference if needed (**CS9120**). +- Ensure that a primary constructor parameter's type doesn't create a cycle in the struct layout. A struct can't contain a field of its own type either directly or indirectly (**CS9121**). ### Readonly struct restrictions -In `readonly struct` types, primary constructor parameters and their members can't be modified outside of init-only setters or variable initializers. Move assignments to field initializers or init-only property setters (**CS9114**, **CS9117**). +- **CS9114**: *A primary constructor parameter of a readonly type cannot be assigned to (except in init-only setter of the type or a variable initializer).* +- **CS9115**: *A primary constructor parameter of a readonly type cannot be returned by writable reference.* +- **CS9116**: *A primary constructor parameter of a readonly type cannot be used as a `ref` or `out` value (except in init-only setter of the type or a variable initializer).* +- **CS9117**: *Members of primary constructor parameter of a readonly type cannot be modified (except in init-only setter of the type or a variable initializer).* +- **CS9118**: *Members of primary constructor parameter of a readonly type cannot be returned by writable reference.* +- **CS9119**: *Members of primary constructor parameter of a readonly type cannot be used as a `ref` or `out` value (except in init-only setter of the type or a variable initializer).* -Primary constructor parameters and their members in `readonly struct` types can't be returned by writable reference. Return by `readonly ref` or by value instead (**CS9115**, **CS9118**). +To address these errors: -Primary constructor parameters and their members in `readonly struct` types can't be passed as `ref` or `out` arguments. Pass them by value or as `in` arguments instead (**CS9116**, **CS9119**). +- In `readonly struct` types, primary constructor parameters and their members can't be modified outside of init-only setters or variable initializers. Move assignments to field initializers or init-only property setters (**CS9114**, **CS9117**). +- Primary constructor parameters and their members in `readonly struct` types can't be returned by writable reference. Return by `readonly ref` or by value instead (**CS9115**, **CS9118**). +- Primary constructor parameters and their members in `readonly struct` types can't be passed as `ref` or `out` arguments. Pass them by value or as `in` arguments instead (**CS9116**, **CS9119**). ### Warnings for captured and shadowed parameters -The following warnings indicate potential issues with how primary constructor parameters are stored or accessed: - -A parameter that's both passed to the base constructor and accessed in the derived type may be stored twice—once in the base class and once in the derived class. Consider whether both copies are necessary, or restructure your code to avoid the duplication (**CS9107**). - -A primary constructor parameter that's never read isn't needed. Remove unused parameters from the primary constructor declaration (**CS9113**). +- **CS9107**: *Parameter is captured into the state of the enclosing type and its value is also passed to the base constructor. The value might be captured by the base class as well.* +- **CS9113**: *Parameter is unread.* +- **CS9124**: *Parameter is captured into the state of the enclosing type and its value is also used to initialize a field, property, or event.* +- **CS9179**: *Primary constructor parameter is shadowed by a member from base.* -A parameter that's both captured by the enclosing type and used to initialize a field, property, or event may be stored twice. Consider using the captured parameter directly instead of initializing a separate member (**CS9124**). +The following warnings indicate potential issues with how primary constructor parameters are stored or accessed: -When a base type member has the same name as a primary constructor parameter, the base member shadows the parameter. Rename the parameter to avoid confusion (**CS9179**). +- A parameter that's both passed to the base constructor and accessed in the derived type may be stored twice—once in the base class and once in the derived class. Consider whether both copies are necessary, or restructure your code to avoid the duplication (**CS9107**). +- A primary constructor parameter that's never read isn't needed. Remove unused parameters from the primary constructor declaration (**CS9113**). +- A parameter that's both captured by the enclosing type and used to initialize a field, property, or event may be stored twice. Consider using the captured parameter directly instead of initializing a separate member (**CS9124**). +- When a base type member has the same name as a primary constructor parameter, the base member shadows the parameter. Rename the parameter to avoid confusion (**CS9179**). +- When a base type member has the same name as a primary constructor parameter, the base member shadows the parameter. Rename the parameter to avoid confusion (**CS9179**). From 7fbc2a29b12de2a54267fee0a16e7c61b508d70d Mon Sep 17 00:00:00 2001 From: Bill Wagner Date: Thu, 29 Jan 2026 10:27:30 -0500 Subject: [PATCH 3/6] Do a proofread --- .../compiler-messages/constructor-errors.md | 66 +++++++++---------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/docs/csharp/language-reference/compiler-messages/constructor-errors.md b/docs/csharp/language-reference/compiler-messages/constructor-errors.md index 9209b07a60291..dc2f76f46719a 100644 --- a/docs/csharp/language-reference/compiler-messages/constructor-errors.md +++ b/docs/csharp/language-reference/compiler-messages/constructor-errors.md @@ -179,7 +179,7 @@ Static constructors initialize static data for a type. For more information, see To correct these errors, ensure your static constructor declaration follows these rules: -- Remove any parameters from the static constructor declaration, because a static constructor must be parameterless (**CS0132**). If you need to pass initialization values, consider using static fields or properties that are set before the static constructor runs. +- Remove any parameters from the static constructor declaration, because a static constructor must be parameterless (**CS0132**). If you need to pass initialization values, consider using static fields or properties that you set before the static constructor runs. - Remove any access modifiers such as `public`, `protected`, `private`, or `internal` from the static constructor, because the runtime controls when the static constructor executes and access modifiers aren't meaningful (**CS0515**). - Remove any `: base()` or `: this()` constructor initializer calls from the static constructor, because static constructors can't chain to other constructors (**CS0514**). The runtime automatically invokes the base class static constructor if one exists. @@ -191,15 +191,15 @@ To correct these errors, ensure your static constructor declaration follows thes - **CS8358**: *Cannot use attribute constructor because it has 'in' parameters.* - **CS8091**: *A constructor cannot be extern and have a constructor initializer.* -Constructors are allowed only in `class` and `struct` types, including `record class` and `record struct` types. For more information, see [Instance Constructors](../../programming-guide/classes-and-structs/instance-constructors.md). +You can declare constructors only in `class` and `struct` types, including `record class` and `record struct` types. For more information, see [Instance Constructors](../../programming-guide/classes-and-structs/instance-constructors.md). -To correct these errors, consider the following guidance: +To fix these errors, try the following suggestions: -Move the constructor to a `class` or `struct` type, because constructors can't be declared in `interface` or `enum` types (**CS0526**, **CS8054**). Interfaces define contracts but don't provide initialization logic, and enum types have their values defined at compile time. +Move the constructor to a `class` or `struct` type, because you can't declare constructors in `interface` or `enum` types (**CS0526**, **CS8054**). Interfaces define contracts but don't provide initialization logic, and enum types have their values defined at compile time. Remove instance constructors from static classes, because static classes can't be instantiated and therefore can't have instance constructors (**CS0710**). If you need initialization logic, use a static constructor instead. -Change `in` parameters to pass-by-value parameters in attribute constructors, because attribute constructors don't support `in` parameter modifiers (**CS8358**). Attributes are instantiated by the runtime using reflection, which doesn't support the `in` modifier. +Change `in` parameters to pass-by-value parameters in attribute constructors, because attribute constructors don't support `in` parameter modifiers (**CS8358**). The runtime instantiates attributes by using reflection, which doesn't support the `in` modifier. Remove the `: base()` or `: this()` constructor initializer from an `extern` constructor, because extern constructors can't chain to other constructors (**CS8091**). The implementation of an extern constructor is provided externally, so constructor chaining isn't possible. @@ -219,9 +219,9 @@ When a constructor is marked `extern`, the compiler can't verify that an impleme Struct types have specific rules for constructors and field initialization. For more information, see the [Struct initialization and default values](../builtin-types/struct.md#struct-initialization-and-default-values) section of the [Structure types](../builtin-types/struct.md) article. -To correct these errors, consider the following guidance: +To fix these errors, try the following suggestions: -- Upgrade to C# 10 or later if you encounter **CS0568** or **CS0573**, because these errors are generated only in older versions of C#. Modern C# allows explicit parameterless constructors and field initializers in structs. +- Upgrade to C# 10 or later if you encounter **CS0568** or **CS0573**, because these errors occur only in older versions of C#. Modern C# allows explicit parameterless constructors and field initializers in structs. - Add the `public` access modifier to any parameterless struct constructor, because parameterless struct constructors must be public to ensure the `default` expression and array allocation can properly initialize struct instances (**CS8958**). - Add a `: this(...)` initializer to explicitly declared constructors in a struct that has a primary constructor, because all non-parameterless constructors must chain to the primary constructor or another explicitly declared constructor to ensure consistent initialization (**CS8982**). - Declare an explicit constructor when your struct uses field initializers, because the compiler requires an explicit constructor to ensure field initializers are invoked (**CS8983**). This constructor can be a parameterless constructor with an empty body. @@ -230,11 +230,11 @@ The following warnings indicate that a field or property isn't explicitly assign - **CS9018**: *Auto-implemented property is read before being explicitly assigned, causing a preceding implicit assignment of 'default'.* - **CS9019**: *Field is read before being explicitly assigned, causing a preceding implicit assignment of 'default'.* -- **CS9020**: *The 'this' object is read before all of its fields have been assigned, causing preceding implicit assignments of 'default' to non-explicitly assigned fields.* +- **CS9020**: *The 'this' object is read before all of its fields are assigned, causing preceding implicit assignments of 'default' to non-explicitly assigned fields.* - **CS9021**: *Control is returned to caller before auto-implemented property is explicitly assigned, causing a preceding implicit assignment of 'default'.* - **CS9022**: *Control is returned to caller before field is explicitly assigned, causing a preceding implicit assignment of 'default'.* -To silence these warnings, explicitly assign all fields and auto-implemented properties before reading them or before control returns from the constructor (**CS9018**, **CS9019**, **CS9020**, **CS9021**, **CS9022**). When unassigned members are read, the compiler implicitly assigns `default` to them, which may not be the intended behavior. +To silence these warnings, explicitly assign all fields and auto-implemented properties before reading them or before control returns from the constructor (**CS9018**, **CS9019**, **CS9020**, **CS9021**, **CS9022**). When unassigned members are read, the compiler implicitly assigns `default` to them, which might not be the intended behavior. ## Constructor calls with `base` and `this` @@ -244,12 +244,12 @@ To silence these warnings, explicitly assign all fields and auto-implemented pro - **CS0768**: *Constructor cannot call itself through another constructor.* - **CS1018**: *Keyword 'this' or 'base' expected.* -Constructor initializers allow one constructor to call another using `: this()` or `: base()`. For more information, see [Using Constructors](../../programming-guide/classes-and-structs/using-constructors.md). +By using constructor initializers, one constructor can call another constructor by using `: this()` or `: base()`. For more information, see [Using Constructors](../../programming-guide/classes-and-structs/using-constructors.md). -To correct these errors, consider the following guidance: +To fix these errors, try the following suggestions: -- Break any circular constructor call chains, because a constructor can't call itself either directly or indirectly through another constructor (**CS0516**, **CS0768**). Ensure that constructor chaining eventually terminates at a constructor that doesn't call another constructor in the same type. -- Remove the `: base()` initializer from constructors in struct types or from constructors in , because these types have no base class constructor to call (**CS0517**, **CS0522**). Struct types implicitly inherit from , but you can't explicitly call its constructor. +- Break any circular constructor call chains, because a constructor can't call itself either directly or indirectly through another constructor (**CS0516**, **CS0768**). Make sure that constructor chaining eventually ends at a constructor that doesn't call another constructor in the same type. +- Remove the `: base()` initializer from constructors in struct types or from constructors in , because these types don't have a base class constructor to call (**CS0517**, **CS0522**). Struct types implicitly inherit from , but you can't explicitly call its constructor. - Complete the constructor initializer or remove the colon (`:`) from the constructor declaration, because when a colon follows a constructor signature, the compiler expects either `this()` or `base()` (**CS1018**). Either add the appropriate constructor call or remove the colon entirely if no chaining is intended. ## Records and copy constructors @@ -258,18 +258,18 @@ To correct these errors, consider the following guidance: - **CS8868**: *A copy constructor in a record must call a copy constructor of the base, or a parameterless object constructor if the record inherits from object.* - **CS8878**: *A copy constructor must be public or protected because the record is not sealed.* - **CS8910**: *The primary constructor conflicts with the synthesized copy constructor.* -In a derived record type, your explicit copy constructor must call the base type's copy constructor using the `: this()` initializer. If the record directly inherits from , it can call the parameterless object constructor instead (**CS8868**). +In a derived record type, your explicit copy constructor must call the base type's copy constructor by using the `: this()` initializer. If the record directly inherits from , it can call the parameterless object constructor instead (**CS8868**). -[Records](../builtin-types/record.md) include a compiler-synthesized [copy constructor](../builtin-types/record.md#nondestructive-mutation). You can write an explicit copy constructor, but it must meet specific requirements. The compiler issues errors when record copy constructors violate these requirements: +[Records](../builtin-types/record.md) include a compiler-synthesized [copy constructor](../builtin-types/record.md#nondestructive-mutation). You can write an explicit copy constructor, but it must meet specific requirements. The compiler generates errors when record copy constructors violate these requirements: - The base type must have an accessible copy constructor. All `record` types have a copy constructor. Ensure the base type is a `record`, or add an accessible copy constructor to it (**CS8867**). -- In a derived record type, your explicit copy constructor must call the base type's copy constructor using the `: this()` initializer. If the record directly inherits from , it can call the parameterless object constructor instead (**CS8868**). +- In a derived record type, your explicit copy constructor must call the base type's copy constructor by using the `: this()` initializer. If the record directly inherits from , it can call the parameterless object constructor instead (**CS8868**). - Copy constructors must be `public` or `protected` unless the record type is [`sealed`](../keywords/sealed.md). Add the appropriate access modifier to the copy constructor (**CS8878**). - If your explicit copy constructor has the same signature as the synthesized copy constructor, the definitions conflict. Remove your explicit copy constructor or modify its signature (**CS8910**). ## Primary constructor declaration -[Primary constructors](../../programming-guide/classes-and-structs/instance-constructors.md#primary-constructors) declare parameters directly in the type declaration. The compiler synthesizes a field to store a primary constructor parameter when it's used in members or field initializers. +[Primary constructors](../../programming-guide/classes-and-structs/instance-constructors.md#primary-constructors) declare parameters directly in the type declaration. The compiler synthesizes a field to store a primary constructor parameter when you use it in members or field initializers. ### Constructor chaining @@ -277,7 +277,7 @@ In a derived record type, your explicit copy constructor must call the base type - **CS8862**: *A constructor declared in a type with parameter list must have 'this' constructor initializer.* - **CS9122**: *Unexpected parameter list.* -When a type has a primary constructor, all other explicitly declared constructors must chain to it using `: this(...)`. Add a `: this(...)` initializer that passes appropriate arguments to the primary constructor (**CS8862**). +When a type has a primary constructor, all other explicitly declared constructors must chain to it by using `: this(...)`. Add a `: this(...)` initializer that passes appropriate arguments to the primary constructor (**CS8862**). Remove a parameter list from the base type reference when the base type doesn't have a primary constructor. The syntax `class Derived : Base(args)` is only valid when `Base` has a primary constructor (**CS8861**). Similarly, remove a primary constructor parameter list from an `interface` declaration, because interfaces can't have primary constructors (**CS9122**). @@ -286,9 +286,9 @@ Remove a parameter list from the base type reference when the base type doesn't - **CS9105**: *Cannot use primary constructor parameter in this context.* - **CS9106**: *Identifier is ambiguous between type and parameter in this context.* -Primary constructor parameters can only be used in the base constructor call when passed as part of the primary constructor declaration. Move the parameter usage to the type declaration's base clause rather than using it in an explicitly declared constructor's `: base()` call (**CS9105**). +You can only use primary constructor parameters in the base constructor call if you pass them as part of the primary constructor declaration. To fix **CS9105**, move the parameter usage to the type declaration's base clause instead of using it in an explicitly declared constructor's `: base()` call. -When a type and a primary constructor parameter have the same name, the reference is ambiguous. Rename either the type or the parameter to resolve the ambiguity (**CS9106**). +If a type and a primary constructor parameter share the same name, the reference becomes ambiguous. To fix **CS9106**, rename either the type or the parameter. ### Ref-like type parameters @@ -299,8 +299,8 @@ When a type and a primary constructor parameter have the same name, the referenc To address these errors: -- Primary constructor parameters of `ref struct` type have restrictions on where they can be used. Move the parameter access out of lambda expressions, query expressions, or local functions (**CS9108**). In types that aren't `ref struct`, access `ref struct` parameters only in field initializers or the constructor body, not in instance members (**CS9110**, **CS9136**). -- For `ref struct` types, primary constructor parameters with `in`, `ref`, or `out` modifiers can't be used in instance methods or property accessors. Copy the parameter value to a field in the constructor and use that field in instance members instead (**CS9109**). +- Primary constructor parameters of `ref struct` type have restrictions on where you can use them. Move the parameter access out of lambda expressions, query expressions, or local functions (**CS9108**). In types that aren't `ref struct`, access `ref struct` parameters only in field initializers or the constructor body, not in instance members (**CS9110**, **CS9136**). +- For `ref struct` types, you can't use primary constructor parameters with `in`, `ref`, or `out` modifiers in instance methods or property accessors. Copy the parameter value to a field in the constructor and use that field in instance members instead (**CS9109**). ### Struct type restrictions @@ -311,8 +311,8 @@ To address these errors: To address these errors: -- In struct types, primary constructor parameters can't be captured in lambda expressions, query expressions, or local functions inside instance members. Copy the parameter to a local variable or field before using it in these contexts (**CS9111**, **CS9112**). -- Primary constructor parameters in struct types can't be returned by reference. Store the value in a field and return that field by reference if needed (**CS9120**). +- In struct types, you can't capture primary constructor parameters in lambda expressions, query expressions, or local functions inside instance members. Copy the parameter to a local variable or field before using it in these contexts (**CS9111**, **CS9112**). +- You can't return primary constructor parameters by reference in struct types. Store the value in a field and return that field by reference if needed (**CS9120**). - Ensure that a primary constructor parameter's type doesn't create a cycle in the struct layout. A struct can't contain a field of its own type either directly or indirectly (**CS9121**). ### Readonly struct restrictions @@ -326,9 +326,9 @@ To address these errors: To address these errors: -- In `readonly struct` types, primary constructor parameters and their members can't be modified outside of init-only setters or variable initializers. Move assignments to field initializers or init-only property setters (**CS9114**, **CS9117**). -- Primary constructor parameters and their members in `readonly struct` types can't be returned by writable reference. Return by `readonly ref` or by value instead (**CS9115**, **CS9118**). -- Primary constructor parameters and their members in `readonly struct` types can't be passed as `ref` or `out` arguments. Pass them by value or as `in` arguments instead (**CS9116**, **CS9119**). +- In `readonly struct` types, you can't modify primary constructor parameters and their members outside of init-only setters or variable initializers. Move assignments to field initializers or init-only property setters (**CS9114**, **CS9117**). +- You can't return primary constructor parameters and their members by writable reference in `readonly struct` types. Return by `readonly ref` or by value instead (**CS9115**, **CS9118**). +- You can't pass primary constructor parameters and their members as `ref` or `out` arguments in `readonly struct` types. Pass them by value or as `in` arguments instead (**CS9116**, **CS9119**). ### Warnings for captured and shadowed parameters @@ -337,10 +337,10 @@ To address these errors: - **CS9124**: *Parameter is captured into the state of the enclosing type and its value is also used to initialize a field, property, or event.* - **CS9179**: *Primary constructor parameter is shadowed by a member from base.* -The following warnings indicate potential issues with how primary constructor parameters are stored or accessed: +The following warnings indicate potential problems with how you store or access primary constructor parameters: -- A parameter that's both passed to the base constructor and accessed in the derived type may be stored twice—once in the base class and once in the derived class. Consider whether both copies are necessary, or restructure your code to avoid the duplication (**CS9107**). -- A primary constructor parameter that's never read isn't needed. Remove unused parameters from the primary constructor declaration (**CS9113**). -- A parameter that's both captured by the enclosing type and used to initialize a field, property, or event may be stored twice. Consider using the captured parameter directly instead of initializing a separate member (**CS9124**). -- When a base type member has the same name as a primary constructor parameter, the base member shadows the parameter. Rename the parameter to avoid confusion (**CS9179**). -- When a base type member has the same name as a primary constructor parameter, the base member shadows the parameter. Rename the parameter to avoid confusion (**CS9179**). +- You might store a parameter twice if you both pass it to the base constructor and access it in the derived type. You might have one copy in the base class and another in the derived class. Consider whether you need both copies, or restructure your code to avoid the duplication (**CS9107**). +- You don't need a primary constructor parameter if you never read it. Remove unused parameters from the primary constructor declaration (**CS9113**). +- You might store a parameter twice if you both capture it in the enclosing type and use it to initialize a field, property, or event. Consider using the captured parameter directly instead of initializing a separate member (**CS9124**). +- A base type member shadows a primary constructor parameter when both have the same name. Rename the parameter to avoid confusion (**CS9179**). +- A base type member shadows a primary constructor parameter when both have the same name. Rename the parameter to avoid confusion (**CS9179**). From 5e58d469e6617067c82daf7c3261708b3438cbe8 Mon Sep 17 00:00:00 2001 From: Bill Wagner Date: Thu, 29 Jan 2026 13:38:23 -0500 Subject: [PATCH 4/6] Apply suggestions from code review Co-authored-by: Meaghan Osagie (Lewis) --- .../compiler-messages/constructor-errors.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/csharp/language-reference/compiler-messages/constructor-errors.md b/docs/csharp/language-reference/compiler-messages/constructor-errors.md index dc2f76f46719a..f5fd771d23746 100644 --- a/docs/csharp/language-reference/compiler-messages/constructor-errors.md +++ b/docs/csharp/language-reference/compiler-messages/constructor-errors.md @@ -175,7 +175,7 @@ In addition, the following warnings are covered in this article: - **CS0514**: *Static constructor cannot have an explicit 'this' or 'base' constructor call.* - **CS0515**: *Access modifiers are not allowed on static constructors.* -Static constructors initialize static data for a type. For more information, see [Static Constructors](../../programming-guide/classes-and-structs/static-constructors.md). +Static constructors initialize static data for a type. For more information, see [Static constructors](../../programming-guide/classes-and-structs/static-constructors.md). To correct these errors, ensure your static constructor declaration follows these rules: @@ -191,7 +191,7 @@ To correct these errors, ensure your static constructor declaration follows thes - **CS8358**: *Cannot use attribute constructor because it has 'in' parameters.* - **CS8091**: *A constructor cannot be extern and have a constructor initializer.* -You can declare constructors only in `class` and `struct` types, including `record class` and `record struct` types. For more information, see [Instance Constructors](../../programming-guide/classes-and-structs/instance-constructors.md). +You can declare constructors only in `class` and `struct` types, including `record class` and `record struct` types. For more information, see [Instance constructors](../../programming-guide/classes-and-structs/instance-constructors.md). To fix these errors, try the following suggestions: @@ -244,7 +244,7 @@ To silence these warnings, explicitly assign all fields and auto-implemented pro - **CS0768**: *Constructor cannot call itself through another constructor.* - **CS1018**: *Keyword 'this' or 'base' expected.* -By using constructor initializers, one constructor can call another constructor by using `: this()` or `: base()`. For more information, see [Using Constructors](../../programming-guide/classes-and-structs/using-constructors.md). +By using constructor initializers, one constructor can call another constructor by using `: this()` or `: base()`. For more information, see [Using constructors](../../programming-guide/classes-and-structs/using-constructors.md). To fix these errors, try the following suggestions: @@ -258,6 +258,7 @@ To fix these errors, try the following suggestions: - **CS8868**: *A copy constructor in a record must call a copy constructor of the base, or a parameterless object constructor if the record inherits from object.* - **CS8878**: *A copy constructor must be public or protected because the record is not sealed.* - **CS8910**: *The primary constructor conflicts with the synthesized copy constructor.* + In a derived record type, your explicit copy constructor must call the base type's copy constructor by using the `: this()` initializer. If the record directly inherits from , it can call the parameterless object constructor instead (**CS8868**). [Records](../builtin-types/record.md) include a compiler-synthesized [copy constructor](../builtin-types/record.md#nondestructive-mutation). You can write an explicit copy constructor, but it must meet specific requirements. The compiler generates errors when record copy constructors violate these requirements: From edae630ff00fdd993a3e8c9152f37d25d826d2a8 Mon Sep 17 00:00:00 2001 From: Bill Wagner Date: Thu, 29 Jan 2026 13:40:27 -0500 Subject: [PATCH 5/6] respond to feedback --- .../language-reference/compiler-messages/constructor-errors.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/csharp/language-reference/compiler-messages/constructor-errors.md b/docs/csharp/language-reference/compiler-messages/constructor-errors.md index f5fd771d23746..3fd7f84b6f058 100644 --- a/docs/csharp/language-reference/compiler-messages/constructor-errors.md +++ b/docs/csharp/language-reference/compiler-messages/constructor-errors.md @@ -344,4 +344,3 @@ The following warnings indicate potential problems with how you store or access - You don't need a primary constructor parameter if you never read it. Remove unused parameters from the primary constructor declaration (**CS9113**). - You might store a parameter twice if you both capture it in the enclosing type and use it to initialize a field, property, or event. Consider using the captured parameter directly instead of initializing a separate member (**CS9124**). - A base type member shadows a primary constructor parameter when both have the same name. Rename the parameter to avoid confusion (**CS9179**). -- A base type member shadows a primary constructor parameter when both have the same name. Rename the parameter to avoid confusion (**CS9179**). From 934e7c3f98f1c15ebd47df33aa8479a9f280190a Mon Sep 17 00:00:00 2001 From: Bill Wagner Date: Thu, 29 Jan 2026 13:41:36 -0500 Subject: [PATCH 6/6] one more fix --- .../language-reference/compiler-messages/constructor-errors.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/csharp/language-reference/compiler-messages/constructor-errors.md b/docs/csharp/language-reference/compiler-messages/constructor-errors.md index 3fd7f84b6f058..c088ac1d73c82 100644 --- a/docs/csharp/language-reference/compiler-messages/constructor-errors.md +++ b/docs/csharp/language-reference/compiler-messages/constructor-errors.md @@ -264,7 +264,7 @@ In a derived record type, your explicit copy constructor must call the base type [Records](../builtin-types/record.md) include a compiler-synthesized [copy constructor](../builtin-types/record.md#nondestructive-mutation). You can write an explicit copy constructor, but it must meet specific requirements. The compiler generates errors when record copy constructors violate these requirements: - The base type must have an accessible copy constructor. All `record` types have a copy constructor. Ensure the base type is a `record`, or add an accessible copy constructor to it (**CS8867**). -- In a derived record type, your explicit copy constructor must call the base type's copy constructor by using the `: this()` initializer. If the record directly inherits from , it can call the parameterless object constructor instead (**CS8868**). +- In a derived record type, your explicit copy constructor must call the base type's copy constructor by using the `: base()` initializer. If the record directly inherits from , it can call the parameterless object constructor instead (**CS8868**). - Copy constructors must be `public` or `protected` unless the record type is [`sealed`](../keywords/sealed.md). Add the appropriate access modifier to the copy constructor (**CS8878**). - If your explicit copy constructor has the same signature as the synthesized copy constructor, the definitions conflict. Remove your explicit copy constructor or modify its signature (**CS8910**).