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:

  • 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.
  • 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.
  • 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

Constructores estáticos

  • 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.

Puede escribir como máximo un constructor estático para un tipo. La declaración de un constructor estático debe cumplir las siguientes reglas:

  • El constructor estático tiene el modificador static, pero ningún otro modificador, como public, protected, privateo internal.
  • El constructor estático debe ser un constructor sin parámetros.
  • El constructor estático no debe llamar a base() ni this(). Si la clase base incluye un constructor estático, el tiempo de ejecución lo llama automáticamente.

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.

Los constructores solo se admiten en los tipos class y struct, incluidos los tipos record class y record struct. No se pueden definir en tipos enum o interface. Además, los tipos de clase de atributo no pueden declarar parámetros in. En su lugar, pase los parámetros por valor.

Sin embargo, puede declarar constructores extern, pero no puede usar llamadas de constructor base() ni this() para llamar a otro constructor desde un constructor declarado extern.

Además, se pueden generar las siguientes advertencias para las declaraciones de constructor:

  • CS0824: El constructor está marcado como externo.

Cuando un constructor está marcado extern, el compilador no puede garantizar que el constructor exista. Por lo tanto, el compilador genera esta advertencia.

Constructores en tipos de estructura

  • CS0568: Structs no puede contener constructores sin parámetros explícitos.
  • 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.

Las características recientes de C# quitan restricciones anteriores a los tipos de struct. CS0568 se genera al declarar un constructor de instancia sin parámetros en versiones anteriores de C#. Puede declarar un constructor de instancia sin parámetros explícito en versiones más recientes de C#. Ese constructor sin parámetros explícito debe ser public. Si struct declara cualquier inicializador de campo, también debe declarar un constructor de instancia explícito. Este constructor puede ser un constructor sin parámetros con un cuerpo vacío.

Cuando un tipo de struct declara un constructor principal, incluidos los tipos de record struct, todos los demás constructores de instancia, excepto un constructor sin parámetros, deben llamar al constructor principal u otro constructor declarado explícitamente mediante this().

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.

Puede usar base() y this() para que un constructor llame a otro en el mismo tipo o en el tipo base. Las llamadas a constructores pueden minimizar la lógica del constructor duplicada. Debe seguir estas reglas al llamar a otro constructor mediante this() o base():

  • Un constructor no puede llamarse directamente o indirectamente a través de otro constructor. Por ejemplo, el código siguiente no es válido:

    public class C
    {
      public C() : this() // Error!
      {
      }
    }
    
    public class C2
    {
      public class C2() : this(10) {}
    
      public class C2(int capacity) : this() 
      {
          _capacity = capacity;
      }
    
      private int _capacity;
    }
    ``
    
    
  • Los tipos de estructura no pueden llamar a base(). Tampoco puede System.Object.

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.

Al agregar el modificador record a un tipo de struct o class, se crea un registro . Los registros incluyen un constructor de copia sintetizado por el compilador. Puede escribir un constructor de copia explícito usted mismo, pero debe cumplir las reglas siguientes:

  • Los constructores de copia deben ser public o protected, a menos que el tipo sea sealed.
  • Los constructores de copia deben llamar al constructor de copia base(), a menos que la clase base sea System.Object.
  • Además, el tipo base debe tener un constructor de copia. Los tipos record siempre tienen un constructor de copia.

Declaración del constructor principal

El compilador emite los siguientes errores cuando un constructor principal infringe una o varias reglas en constructores principales para clases y estructuras:

  • CS8861: Lista de argumentos inesperados.
  • CS8862: Un constructor declarado en un tipo con lista de parámetros debe tener inicializador de constructor "this".
  • 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.
  • 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 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.
  • 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).
  • 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.
  • 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.
  • CS9136: No se puede usar el parámetro de constructor principal de tipo dentro de un miembro de instancia.

Los parámetros del constructor principal están en el ámbito del cuerpo de ese tipo. El compilador puede sintetizar un campo que almacena el parámetro para su uso en miembros o en inicializadores de campo. Dado que se puede copiar un parámetro de constructor principal en un campo, se aplican las restricciones siguientes:

  • Los constructores principales se pueden declarar en tipos de struct y class, pero no en tipos de interface.
  • Los parámetros del constructor principal no se pueden usar en una llamada de constructor base(), excepto como parte del constructor principal.
  • No se puede tener acceso a los parámetros de constructor principal de ref struct tipo en expresiones lambda, expresiones de consulta ni funciones locales.
  • Si el tipo no es ref struct, no se puede acceder a los parámetros ref struct en miembros de instancia.
  • En un tipo ref struct, los parámetros del constructor principal con los modificadores in, refo out no pueden usarse en ningún método de instancia ni en los accesores de propiedad.

Los tipos de estructura tienen las siguientes restricciones adicionales en los parámetros del constructor principal:

  • Los parámetros de constructor principal no se pueden capturar en expresiones lambda, expresiones de consulta ni funciones locales.
  • Los parámetros del constructor principal no se pueden devolver por referencia (ref retorno o readonly ref retorno).

Los tipos de estructura de solo lectura tienen las siguientes restricciones adicionales en los parámetros del constructor principal:

  • Los parámetros del constructor principal y sus miembros no se pueden reasignar en una estructura de readonly.
  • Los parámetros del constructor principal y sus miembros no se pueden ser valores devueltos ref en una estructura readonly.
  • Los parámetros del constructor principal y sus miembros no pueden ser ref o out argumentos de ningún método.

En todos estos casos, las restricciones en los parámetros del constructor principal son coherentes con las restricciones en los campos de datos de esos tipos. Las restricciones se deben a que un parámetro de constructor principal se puede transformar en un campo sintetizado en el tipo . Por lo tanto, los parámetros del constructor principal deben seguir las reglas que se aplican a ese campo sintetizado.

Un constructor principal derivado llama al constructor principal base proporcionando los parámetros al constructor base. Debe usar los nombres de parámetro de la declaración de constructor derivada.

Las advertencias proporcionan instrucciones sobre los parámetros de constructor principal capturados o 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. Esta advertencia indica que el código se puede asignar dos copias de un parámetro de constructor principal. Dado que el parámetro se pasa a la clase base, es probable que la clase base la use. Dado que la clase derivada accede a ella, puede tener una segunda copia del mismo parámetro. Es posible que ese almacenamiento adicional no esté pensado.
  • CS9113: El parámetro no se ha leído. Esta advertencia indica que la clase nunca hace referencia al constructor principal, incluso para pasarla al constructor principal base. Es probable que no sea necesario.
  • CS9124: El parámetro se captura en el estado del tipo contenedor, y se utiliza su valor también para inicializar un campo, una propiedad o un evento. Esta advertencia indica que el parámetro del constructor de un tipo anidado también se captura mediante el tipo contenedor. Es probable que el parámetro se almacene dos veces.
  • CS9179: El parámetro de constructor principal está sombreado por un miembro de la base