Compartir a través de


Resolución de errores y advertencias en declaraciones de constructor

En este artículo se tratan los siguientes errores del compilador:

  • CS0132: 'constructor': un constructor estático debe ser sin parámetros.
  • El constructor estático no puede tener una llamada explícita al constructor "this" o "base". CS0514:
  • CS0515: no se permiten modificadores de acceso en constructores estáticos.
  • CS0516: El constructor 'constructor' no se puede llamar a sí mismo.
  • CS0517: "class" no tiene ninguna clase base y no puede llamar a un constructor base.
  • CS0522: structs no pueden llamar a constructores de clase base.
  • CS0526: las interfaces de no pueden contener constructores.
  • CS0568: Structs no puede contener constructores sin parámetros explícitos.
  • CS0573: 'declaración de campo': no puede tener inicializadores de campo de instancia en estructuras.
  • CS0710: las clases estáticas no pueden tener constructores de instancia.
  • CS0768: El constructor no puede llamarse a sí mismo a través de otro constructor.
  • CS1018: se esperaba la palabra clave 'this' o 'base'.
  • CS8054: Enums no puede contener constructores explícitos sin parámetros.
  • CS8091: no puede ser externo ni tener un inicializador de constructor.
  • CS8861: Lista de argumentos inesperados.
  • CS8862: Un constructor declarado en un tipo con lista de parámetros debe tener inicializador de constructor "this".
  • CS8358: No se puede usar el constructor de atributos porque tiene parámetros "in".
  • CS8867: No se encontró ningún constructor de copia accesible en el tipo base "{0}".
  • CS8868: un constructor de copia de un registro debe llamar a un constructor de copia de la base o a un constructor de objetos sin parámetros si el registro hereda del objeto .
  • CS8878: Un constructor de copia '{0}' debe ser público o protegido porque el registro no está sellado.
  • CS8910: El constructor principal entra en conflicto con el constructor de copia sintetizado.
  • CS8958: El constructor de estructura sin parámetros debe ser "public".
  • CS8982: Un constructor declarado en un "struct" con la lista de parámetros debe tener un inicializador "this" que llame al constructor principal o a un constructor declarado explícitamente.
  • CS8983: un "struct" con inicializadores de campo debe incluir un constructor declarado explícitamente.
  • CS9105: No se puede usar el parámetro de constructor principal en este contexto.
  • CS9106: el identificador es ambiguo entre el tipo y el parámetro en este contexto.
  • CS9108: No se puede usar el parámetro con tipo ref dentro de un método anónimo, expresión lambda, expresión de consulta o función local.
  • CS9109: No se puede usar ref, outo in parámetro de constructor principal dentro de un miembro de instancia.
  • CS9110: No se puede usar el parámetro de constructor principal que tenga tipo ref-like dentro de un miembro de instancia.
  • CS9111: métodos anónimos, expresiones lambda, expresiones de consulta y funciones locales dentro de un miembro de instancia de un struct no puede tener acceso al parámetro del constructor principal.
  • CS9112: métodos anónimos, expresiones lambda, expresiones de consulta y funciones locales dentro de una estructura no puede tener acceso al parámetro de constructor principal que también se usa dentro de un miembro de instancia.
  • CS9114: No se puede asignar un parámetro de constructor principal de un tipo de solo lectura (excepto en el establecedor de solo inicialización de tipo o variable).
  • CS9115: Un parámetro de constructor principal de un tipo readonly no se puede devolver mediante referencia escribible.
  • CS9116: Un parámetro de constructor principal de un tipo solo lectura no se puede usar como valor ref o out (excepto en el establecedor de solo inicialización del tipo o de una variable).
  • CS9117: Los miembros del parámetro de constructor principal de un tipo de solo lectura no se pueden modificar (excepto en el establecedor de solo inicialización de tipo o variable).
  • CS9118: La referencia grabable no puede devolver los miembros del parámetro constructor principal de un tipo de solo lectura.
  • CS9119: Los miembros del parámetro de constructor principal de un tipo de solo lectura no se pueden usar como un valor ref o out (excepto en el establecedor de solo inicialización de tipo o variable).
  • CS9120: No se puede devolver el parámetro de constructor principal por referencia.
  • CS9121: El parámetro de constructor principal de struct de tipo provoca un ciclo en el diseño de la estructura.
  • CS9122: lista de parámetros inesperados.
  • CS9136: No se puede usar el parámetro de constructor principal de tipo dentro de un miembro de instancia.

Además, en este artículo se tratan las siguientes advertencias:

  • CS0824: El constructor 'name' está marcado como externo.
  • CS9107: El parámetro se registra en el estado del tipo envolvente y su valor se pasa al constructor base. El valor puede ser capturado por la clase base también.
  • CS9113: El parámetro no está leído.
  • CS9124: El parámetro se captura en el estado del tipo envolvente y su valor también se usa para inicializar un campo, una propiedad o un evento.
  • CS9179: El parámetro del constructor principal está ocultado por un miembro de la clase base
  • CS9018: se lee la propiedad implementada automáticamente antes de asignarse explícitamente, lo que provoca una asignación implícita anterior de "default".
  • CS9019: el campo se lee antes de asignarse explícitamente, lo que provoca una asignación implícita anterior de "valor predeterminado".
  • CS9020: el objeto 'this' se lee antes de que se hayan asignado todos sus campos, lo que provoca asignaciones implícitas anteriores de 'default' a campos no asignados explícitamente.
  • CS9021: el control se devuelve al autor de la llamada antes de asignar explícitamente la propiedad implementada automáticamente, lo que provoca una asignación implícita anterior de "default".
  • CS9022: el control se devuelve al autor de la llamada antes de asignar explícitamente el campo, lo que provoca una asignación implícita anterior de "default".

Constructores estáticos

  • CS0132: 'constructor': un constructor estático debe ser sin parámetros.
  • CS0514: el constructor estático no puede tener una llamada explícita al constructor 'this' o 'base'.
  • CS0515: No se permiten modificadores de acceso en constructores estáticos.

Los constructores estáticos inicializan datos estáticos para un tipo. Para obtener más información, vea Constructores estáticos.

Para corregir estos errores, asegúrese de que la declaración del constructor estático sigue estas reglas:

  • Quite los parámetros de la declaración de constructor estático, ya que un constructor estático debe ser sin parámetros (CS0132). Si necesita pasar valores de inicialización, considere la posibilidad de usar campos estáticos o propiedades que establezca antes de que se ejecute el constructor estático.
  • Quite los modificadores de acceso como public, protected, privateo internal del constructor estático, ya que el tiempo de ejecución controla cuando el constructor estático ejecuta y los modificadores de acceso no son significativos (CS0515).
  • Quite las llamadas de inicializador de : base() o : this() del constructor estático, ya que los constructores estáticos no pueden llamar a otros constructores (CS0514). El tiempo de ejecución invoca automáticamente el constructor estático de clase base si existe uno.

Declaración del constructor

  • CS0526: las interfaces de no pueden contener constructores.
  • CS0710: las clases estáticas no pueden tener constructores de instancia.
  • CS8054: Enums no puede contener constructores sin parámetros explícitos.
  • CS8358: No se puede usar el constructor de atributos porque tiene parámetros "in".
  • CS8091: Un constructor no puede ser externo y tener un inicializador de constructor.

Solo puede declarar constructores en tipos class y struct, incluyendo tipos record class y record struct. Para obtener más información, consulte Constructores de instancias.

Para corregir estos errores, pruebe las siguientes sugerencias:

Mueva el constructor a un class tipo o struct porque no se pueden declarar constructores en interface tipos o enum (CS0526, CS8054). Las interfaces definen contratos, pero no proporcionan lógica de inicialización y los tipos de enumeración tienen sus valores definidos en tiempo de compilación.

Quite constructores de instancia de clases estáticas, ya que no se pueden crear instancias de clases estáticas y, por tanto, no pueden tener constructores de instancia (CS0710). Si necesita lógica de inicialización, use un constructor estático en su lugar.

Cambie in los parámetros a parámetros de paso por valor en constructores de atributos, ya que los constructores de atributos no admiten in modificadores de parámetros (CS8358). El tiempo de ejecución crea instancias de los atributos mediante reflexión, que no admite el modificador in.

Quite el inicializador : base() o : this() de un extern constructor, porque los constructores externos no pueden encadenarse a otros constructores (CS8091). La implementación de un constructor externo se proporciona fuera del código, lo que hace que el encadenamiento de constructores no sea posible.

Se puede generar la siguiente advertencia para las declaraciones de constructor:

  • CS0824: El constructor está marcado como externo.

Cuando un constructor está marcado externcomo , el compilador no puede comprobar que existe una implementación. Para suprimir esta advertencia, proporcione una implementación interna o asegúrese de que la implementación externa esté vinculada correctamente.

Constructores en tipos de estructura

  • CS0568: Structs no puede contener constructores sin parámetros explícitos.
  • CS0573: 'declaración de campo': no puede tener inicializadores de campo de instancia en estructuras.
  • CS8958: El constructor de estructura sin parámetros debe ser "public".
  • CS8982: Un constructor declarado en un "struct" con la lista de parámetros debe tener un inicializador "this" que llame al constructor principal o a un constructor declarado explícitamente.
  • CS8983: un "struct" con inicializadores de campo debe incluir un constructor declarado explícitamente.

Los tipos de estructura tienen reglas específicas para constructores y inicialización de campos. Para obtener más información, consulte la sección Inicialización de estructura y valores predeterminados del artículo Tipos de estructura.

Para corregir estos errores, pruebe las siguientes sugerencias:

  • Actualice a C# 10 o posterior si encuentra CS0568 o CS0573, ya que estos errores solo se producen en versiones anteriores de C#. C# moderno permite constructores y inicializadores de campo explícitos sin parámetros en estructuras.
  • Agregue el public modificador de acceso a cualquier constructor de estructura sin parámetros, ya que los constructores de estructura sin parámetros deben ser públicos para asegurarse de que la default asignación de expresiones y matrices puede inicializar correctamente instancias de estructura (CS8958).
  • Agregue un : this(...) inicializador a constructores declarados explícitamente en una estructura que tenga un constructor principal, ya que todos los constructores sin parámetros deben encadenar al constructor principal u otro constructor declarado explícitamente para garantizar una inicialización coherente (CS8982).
  • Declare un constructor explícito cuando la estructura use inicializadores de campo, ya que el compilador requiere un constructor explícito para asegurarse de que se invocan inicializadores de campo (CS8983). Este constructor puede ser un constructor sin parámetros con un cuerpo vacío.

Las advertencias siguientes indican que un campo o propiedad no está asignado explícitamente antes de leerse o antes de que el control vuelva al autor de la llamada:

  • CS9018: se lee la propiedad implementada automáticamente antes de asignarse explícitamente, lo que provoca una asignación implícita anterior de "default".
  • CS9019: el campo se lee antes de asignarse explícitamente, lo que provoca una asignación implícita anterior de "valor predeterminado".
  • CS9020: El objeto "this" se lee antes de que se asignen todos sus campos, lo que provoca las asignaciones previas implícitas de "default" a los campos que no se asignan explícitamente.
  • CS9021: el control se devuelve al autor de la llamada antes de asignar explícitamente la propiedad implementada automáticamente, lo que provoca una asignación implícita anterior de "default".
  • CS9022: el control se devuelve al autor de la llamada antes de asignar explícitamente el campo, lo que provoca una asignación implícita anterior de "default".

Para silenciar estas advertencias, asigne explícitamente todos los campos y propiedades implementadas automáticamente antes de leerlas o antes de que el control vuelva del constructor (CS9018, CS9019, CS9020, CS9021, CS9022). Cuando se leen miembros no asignados, el compilador les asigna default implícitamente, lo que podría no ser el comportamiento estipulado.

Llamadas de constructor con base y this

  • CS0516: El constructor no puede llamarse a sí mismo.
  • CS0517: 'class' no tiene ninguna clase base y no puede llamar a un constructor base.
  • CS0522: Structs no puede llamar a constructores de clase base.
  • CS0768: El constructor no puede llamarse a sí mismo a través de otro constructor.
  • CS1018: se esperaba la palabra clave 'this' o 'base'.

Mediante el uso de inicializadores de constructor, un constructor puede llamar a otro constructor mediante : this() o : base(). Para obtener más información, consulte Uso de constructores.

Para corregir estos errores, pruebe las siguientes sugerencias:

  • Interrumpa cualquier cadena de llamadas de constructor circular, ya que un constructor no puede llamarse directamente o indirectamente a través de otro constructor (CS0516, CS0768). Asegúrese de que el encadenamiento de constructores termina finalmente en un constructor que no llama a otro constructor en el mismo tipo.
  • Quite el inicializador de constructores de tipos 'struct' o de otros constructores en System.Object, ya que estos tipos no tienen un constructor de clase base al cual llamar (CS0517, CS0522). Los tipos de estructura heredan implícitamente de System.ValueType, pero no se puede llamar explícitamente a su constructor.
  • Completa el inicializador del constructor o quita los dos puntos (:) de la declaración del constructor, ya que cuando un signo de dos puntos sigue la firma de un constructor, el compilador espera this() o base() (CS1018). Agregue la llamada al constructor adecuada o quite completamente los dos puntos si no se pretende encadenar ningún encadenamiento.

Registros y constructores de copia

  • CS8867: No se encontró ningún constructor de copia accesible en el tipo base.
  • CS8868: Un constructor de copia de un registro debe llamar a un constructor de copia de la base o a un constructor de objetos sin parámetros si el registro hereda del objeto .
  • CS8878: Un constructor de copia debe ser público o protegido porque el registro no está sellado.
  • CS8910: El constructor principal entra en conflicto con el constructor de copia sintetizado.

En un tipo de registro derivado, su constructor de copia explícito debe llamar al constructor de copia del tipo base utilizando el inicializador : this(). Si el registro hereda directamente de System.Object, puede llamar al constructor de objetos sin parámetros (CS8868).

Los registros incluyen un constructor de copia sintetizado por el compilador. Puede escribir un constructor de copia explícito, pero debe cumplir requisitos específicos. El compilador genera errores cuando los constructores de copia de registros infringen estos requisitos:

  • El tipo base debe tener un constructor de copia accesible. Todos los record tipos tienen un constructor de copia. Asegúrese de que el tipo base sea un record, o agregue un constructor de copia accesible a este (CS8867).
  • En un tipo de registro derivado, el constructor de copia explícito debe llamar al constructor de copia del tipo base usando el inicializador : base(). Si el registro hereda directamente de System.Object, puede llamar al constructor de objetos sin parámetros (CS8868).
  • Los constructores de copia deben ser public o protected a menos que el tipo de registro sea sealed. Agregue el modificador de acceso adecuado al constructor de copia (CS8878).
  • Si el constructor de copia explícito tiene la misma firma que el constructor de copia sintetizado, las definiciones entran en conflicto. Quite el constructor de copia explícito o modifique su firma (CS8910).

Declaración del constructor principal

Los constructores principales declaran parámetros directamente en la declaración de tipo. El compilador sintetiza un campo para almacenar un parámetro de constructor principal cuando se usa en miembros o inicializadores de campo.

Encadenamiento de constructores

  • CS8861: Lista de argumentos inesperados.
  • CS8862: Un constructor declarado en un tipo con lista de parámetros debe tener inicializador de constructor "this".
  • CS9122: Lista de parámetros inesperados.

Cuando un tipo tiene un constructor principal, todos los demás constructores declarados explícitamente deben encadenarlo mediante : this(...). Agregue un : this(...) inicializador que pase los argumentos adecuados al constructor principal (CS8862).

Quite una lista de parámetros de la referencia de tipo base cuando el tipo base no tenga un constructor principal. La sintaxis class Derived : Base(args) solo es válida cuando Base tiene un constructor principal (CS8861). De forma similar, quite una lista de parámetros de constructor principal de una interface declaración, ya que las interfaces no pueden tener constructores principales (CS9122).

Uso de parámetros en llamadas de constructor base

  • CS9105: No se puede usar el parámetro de constructor principal en este contexto.
  • CS9106: el identificador de es ambiguo entre el tipo y el parámetro en este contexto.

Solo puede usar parámetros de constructor principal en la llamada al constructor base si los pasa como parte de la declaración del constructor principal. Para corregir CS9105, mueva el uso del parámetro a la cláusula base de la declaración de tipo en lugar de usarlo en la llamada de un constructor declarado explícitamente con : base().

Si un tipo y un parámetro de constructor principal comparten el mismo nombre, la referencia se convierte en ambigua. Para corregir el error CS9106, cambie el nombre del tipo o del parámetro .

Parámetros de tipo ref-like

  • CS9108: No se puede usar el parámetro con tipo ref dentro de un método anónimo, expresión lambda, expresión de consulta o función local.
  • CS9109: No se puede usar ref, outo in parámetro de constructor principal dentro de un miembro de instancia.
  • CS9110: No se puede usar el parámetro de constructor principal que tenga tipo ref-like dentro de un miembro de instancia.
  • CS9136: No se puede usar el parámetro de constructor principal de tipo dentro de un miembro de instancia.

Para solucionar estos errores:

  • Los parámetros de constructor principal de ref struct tipo tienen restricciones sobre dónde se pueden usar. Mueva el acceso al parámetro fuera de las expresiones lambda, las expresiones de consulta o las funciones locales (CS9108). En tipos que no sean ref struct, acceda a los parámetros ref struct solo en inicializadores de campo o en el cuerpo del constructor, no en miembros de instancia (CS9110, CS9136).
  • Para tipos ref struct, no se pueden usar parámetros de constructor principal con modificadores in, ref o out en métodos de instancia o descriptores de acceso de propiedad. Copie el valor del parámetro en un campo del constructor y use ese campo en miembros de instancia (CS9109).

Restricciones de tipo de estructura

  • CS9111: métodos anónimos, expresiones lambda, expresiones de consulta y funciones locales dentro de un miembro de instancia de un struct no pueden tener acceso al parámetro de constructor principal.
  • CS9112: Los métodos anónimos, expresiones lambda, expresiones de consulta y funciones locales dentro de una estructura no pueden acceder al parámetro del constructor principal que también se usa dentro de un miembro de instancia.
  • CS9120: No se puede devolver el parámetro de constructor principal por referencia.
  • CS9121: El parámetro de constructor principal de struct de tipo provoca un ciclo en el diseño de la estructura.

Para solucionar estos errores:

  • En los tipos de estructura, no se pueden capturar parámetros del constructor primario en expresiones lambda, expresiones de consulta ni funciones locales dentro de los miembros de instancia. Copie el parámetro en una variable o campo local antes de usarlo en estos contextos (CS9111, CS9112).
  • No se pueden devolver parámetros del constructor primario por referencia en tipos de estructura. Almacene el valor en un campo y devuelva ese campo por referencia si es necesario (CS9120).
  • Asegúrese de que el tipo de un parámetro de constructor principal no cree un ciclo en el diseño de estructura. Una estructura no puede contener un campo de su propio tipo directa o indirectamente (CS9121).

Restricciones de estructura de solo lectura

  • CS9114: No se puede asignar un parámetro de constructor principal de un tipo de solo lectura (excepto en el establecedor de solo inicialización de tipo o variable).
  • CS9115: Una referencia grabable no puede devolver un parámetro de constructor principal de un tipo de solo lectura.
  • CS9116: No se puede usar un parámetro de constructor principal de un tipo de solo lectura como un valor de ref o out (excepto en el establecedor de solo inicialización de inicialización de inicializadores de tipo o variable).
  • CS9117: Los miembros del parámetro de constructor principal de un tipo de solo lectura no se pueden modificar (excepto en el establecedor de solo inicialización de tipo o variable).
  • CS9118: La referencia grabable no puede devolver los miembros del parámetro constructor principal de un tipo de solo lectura.
  • CS9119: Los miembros del parámetro de constructor principal de un tipo de solo lectura no se pueden usar como un valor ref o out (excepto en el establecedor de solo inicialización de tipo o variable).

Para solucionar estos errores:

  • En los tipos readonly struct, no se pueden modificar los parámetros del constructor principal y sus miembros fuera de los establecedores solo de inicialización o los inicializadores de variables. Mover asignaciones a inicializadores de campo o establecedores de propiedades de solo inicialización (CS9114, CS9117).
  • No se pueden devolver por referencia escribible parámetros del constructor principal y sus miembros en tipos readonly struct. Devuelve mediante readonly ref o por valor (CS9115, CS9118).
  • No se pueden pasar parámetros de constructor principal y sus miembros como argumentos de ref o out en tipos readonly struct. Pásalos por valor o como argumentos (in) en su lugar (CS9116, CS9119).

Advertencias para parámetros capturados y sombreados

  • CS9107: el parámetro se captura en el estado del tipo envolvente y su valor también se pasa al constructor base. El valor también se puede capturar mediante la clase base.
  • CS9113: el parámetro no es leído.
  • CS9124: El parámetro se captura en el estado del tipo envolvente y su valor también se usa para inicializar un campo, una propiedad o un evento.
  • CS9179: el parámetro del constructor principal es sombreado por un miembro de base.

Las advertencias siguientes indican posibles problemas con la forma de almacenar o acceder a los parámetros de constructor principal:

  • Puede almacenar un parámetro dos veces si ambos lo pasan al constructor base y acceden a él en el tipo derivado. Es posible que tenga una copia en la clase base y otra en la clase derivada. Considere si necesita ambas copias o reestructura el código para evitar la duplicación (CS9107).
  • No necesita un parámetro de constructor principal si nunca lo lee. Quite los parámetros sin usar de la declaración del constructor principal (CS9113).
  • Puede almacenar un parámetro dos veces si ambos lo capturan en el tipo envolvente y lo usan para inicializar un campo, una propiedad o un evento. Considere la posibilidad de usar el parámetro capturado directamente en lugar de inicializar un miembro independiente (CS9124).
  • Un miembro de tipo base sombrea un parámetro de constructor principal cuando ambos tienen el mismo nombre. Cambie el nombre del parámetro para evitar confusiones (CS9179).