Compartir a través de


Resolución de errores y advertencias para declaraciones de operadores y desbordamientos

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

  • CS0031: El valor constante 'value' no se puede convertir en un 'type'
  • CS0056: Accesibilidad incoherente: el tipo de valor devuelto 'type' es menos accesible que el operador 'operator'
  • CS0057: Accesibilidad incoherente: el tipo de parámetro 'type' es menos accesible que el operador 'operator'
  • CS0215: el tipo de valor devuelto del operador True o False debe ser bool.
  • CS0216: el operador 'operator' requiere que también se defina un operador coincidente 'missing_operator'
  • CS0217: para que sea aplicable como operador de cortocircuito, un operador lógico definido por el usuario ('operator') debe tener el mismo tipo de valor devuelto que el tipo de sus 2 parámetros.
  • CS0218: el tipo ('type') debe contener declaraciones del operador true y el operador false
  • CS0220: la operación se desborda en tiempo de compilación en modo comprobado
  • CS0221: El valor constante 'value' no se puede convertir en un 'type' (use la sintaxis 'unchecked' para invalidar)
  • CS0448: El tipo de retorno del operador ++ o -- debe ser el tipo contenedor o estar derivado del tipo contenedor.
  • CS0463: Error en la evaluación de la expresión constante decimal con error: 'error'
  • CS0543: 'enumeration': el valor del enumerador es demasiado grande para caber en su tipo
  • CS0552: "rutina de conversión" : conversión definida por el usuario a o desde la interfaz
  • CS0553: "rutina de conversión" : conversión definida por el usuario a o desde la clase base
  • CS0554: "rutina de conversión" : conversión definida por el usuario a o desde la clase derivada
  • CS0555: El operador definido por el usuario no puede tomar un objeto del tipo envolvente ni convertirlo en un objeto del tipo envolvente
  • CS0556: La conversión definida por el usuario debe convertir a o desde el tipo que lo contiene
  • CS0557: Conversión duplicada definida por el usuario en el tipo
  • CS0558: El operador definido por el usuario debe declararse estático y público
  • CS0559: El tipo de parámetro para el operador ++ o -- debe ser el tipo que lo contiene
  • CS0562: el parámetro de un operador unario debe ser el tipo contenedor.
  • CS0563: uno de los parámetros de un operador binario debe ser el tipo contenedor.
  • CS0564: El primer operando de un operador de desplazamiento sobrecargado debe tener el mismo tipo que aquel que lo contiene, y el tipo del segundo operando debe ser int.
  • CS0567: Las interfaces no pueden contener operadores
  • CS0590: Los operadores definidos por el usuario no pueden devolver void
  • CS0594: la constante de punto flotante está fuera del rango del tipo 'type'
  • CS0652: La comparación con constante integral es inútil; la constante está fuera del intervalo de tipo 'type'
  • CS0659: 'class' invalida Object.Equals(object o), pero no invalida Object.GetHashCode()
  • CS0660: el tipo define operator == o operator != pero no invalida Object.Equals(object o)
  • CS0661: El tipo define operator == o operator != pero no invalida Object.GetHashCode()
  • CS0715: Las clases estáticas no pueden contener operadores definidos por el usuario
  • CS1021: la constante integral es demasiado grande
  • CS1037: Se esperaba un operador sobrecargable
  • CS1553: La declaración no es válida; use 'operador modificador <dest-type> (...' en lugar de
  • CS8930: La implementación explícita de un operador definido por el usuario debe declararse estática.
  • CS8931: La conversión definida por el usuario en una interfaz debe convertir en o desde un parámetro de tipo en el tipo envolvente restringido al tipo envolvente.
  • CS8778: el valor constante 'value' puede desbordar 'type' en tiempo de ejecución (use la sintaxis 'unchecked' para invalidar)
  • CS8973: La operación puede desbordarse en tiempo de ejecución (use la sintaxis "desactivada" para invalidar)
  • CS9023: El operador no puede ser comprobado.
  • CS9024: No se puede poner al operador en estado no comprobado.
  • CS9025: el operador requiere que también se declare una versión no comprobada coincidente.
  • CS9027: palabra clave inesperada 'unchecked'.
  • CS9308: el operador definido por el usuario debe declararse público.
  • CS9310: el tipo de valor devuelto para este operador debe ser nulo.
  • CS9311: El tipo no implementa el miembro de interfaz. El tipo no puede implementar miembro porque uno de ellos no es un operador.
  • CS9312: El tipo no puede invalidar el miembro heredado porque uno de ellos no es un operador.
  • CS9313: El operador de asignación compuesta sobrecargado toma un parámetro.
  • CS9340: el operador no se puede aplicar a los operandos. Se muestra el candidato inaplicable más cercano.
  • CS9341: el operador no se puede aplicar al operando. Se muestra el candidato inaplicable más cercano.
  • CS9342: la resolución del operador es ambigua entre los siguientes miembros.

Requisitos de firma de operador

  • CS0448: El tipo de valor devuelto para el operador ++ o -- debe ser el tipo contenedor o derivado del tipo contenedor.
  • CS0559: el tipo de parámetro para ++ o -- el operador debe ser el tipo contenedor.
  • CS0562: el parámetro de un operador unario debe ser el tipo contenedor.
  • CS0563: uno de los parámetros de un operador binario debe ser el tipo contenedor.
  • CS0564: El primer operando de un operador de desplazamiento sobrecargado debe tener el mismo tipo que el tipo contenedor, y el tipo del segundo operando debe ser int.
  • CS0567: Las interfaces no pueden contener operadores.
  • CS0590: los operadores definidos por el usuario no pueden devolver void.
  • CS9310: el tipo de valor devuelto para este operador debe ser nulo.
  • CS9340: el operador no se puede aplicar a los operandos. Se muestra el candidato inaplicable más cercano.
  • CS9341: el operador no se puede aplicar al operando. Se muestra el candidato inaplicable más cercano.
  • CS9342: la resolución del operador es ambigua entre los siguientes miembros.

Cada tipo de operador tiene requisitos específicos de parámetro y tipo de valor devuelto definidos por la especificación del lenguaje. Para obtener las reglas completas sobre qué operadores se pueden sobrecargar, consulte Sobrecarga de operadores y Operadores en la especificación de C#.

  • Cambie el tipo de valor devuelto de los operadores ++ o -- al tipo contenedor o a un tipo derivado de este (CS0448). El lenguaje requiere que los operadores de incremento y decremento devuelvan un valor compatible con el tipo contenedor para que el resultado se pueda volver a asignar a la misma variable.
  • Cambie el parámetro de los operadores ++ o -- al tipo contenedor (CS0559). Los operadores de incremento y decremento deben funcionar en instancias de su propio tipo.
  • Cambie el parámetro de un operador unario al tipo contenedor (CS0562). Los operadores unarios deben aceptar un operando del tipo que los declara.
  • Asegúrese de que al menos un parámetro de un operador binario es el tipo contenedor (CS0563). Los operadores binarios deben implicar el tipo declarativo para que el compilador pueda resolverlos a través de ese tipo.
  • Cambie el primer parámetro de un operador shift al tipo que lo contiene y el segundo parámetro a int (CS0564). El lenguaje define operadores de desplazamiento con una firma específica: el tipo que se desplaza y una cantidad de desplazamiento entero.
  • Mueva las declaraciones de operador fuera de las interfaces y a las clases o estructuras (CS0567). Las declaraciones de operador tradicionales (abstractas no estáticas) no se permiten en interfaces. Para los operadores abstractos estáticos en interfaces, consulte Errores de miembro de interfaz virtual y abstracta estática.
  • Cambie el tipo de valor devuelto del operador a un tipo que no sea void (CS0590). La mayoría de los operadores definidos por el usuario deben devolver un valor. La excepción es operadores de asignación compuestos, que requieren un void tipo de valor devuelto (CS9310).
  • Corrija los tipos de parámetros o agregue sobrecargas de operador que faltan para que el compilador pueda encontrar un operador coincidente para los tipos de operando usados en el sitio de llamada (CS9340, CS9341). Cuando no existe ningún operador aplicable, el compilador muestra el candidato más cercano para ayudar a diagnosticar la falta de coincidencia.
  • Agregue conversiones explícitas en el sitio de llamada o proporcione sobrecargas más específicas para eliminar la ambigüedad cuando varias sobrecargas del operador coinciden igual de bien (CS9342).

Importante

Los requisitos de firma para los operadores binarios estáticos y los operadores de asignación compuesta de instancia correspondientes son diferentes. Asegúrese de que la firma coincide con la declaración que desee.

Requisitos de declaración de operador

  • CS0558: el operador definido por el usuario debe declararse estático y público.
  • CS0715: las clases estáticas no pueden contener operadores definidos por el usuario.
  • CS1037: se esperaba un operador sobrecargable.
  • CS1553: La declaración no es válida; use 'modificador operator <dest-type> (...' en su lugar.
  • CS9308: el operador definido por el usuario debe declararse público.

El lenguaje requiere modificadores y sintaxis específicos para las declaraciones de operador. Para obtener las reglas completas, consulte Sobrecarga deoperadores y operadores de conversión definidos por el usuario.

  • Agregue los static modificadores y public a la declaración de operador (CS0558, CS9308). El lenguaje C# requiere que todos los operadores definidos por el usuario sean estáticos y públicos para que sean accesibles y llamables sin necesidad de una instancia.
  • Mueva la declaración del operador de una clase estática a una clase o estructura no estática (CS0715). Las clases estáticas no pueden tener instancias, por lo que los operadores definidos por el usuario (que operan en instancias de su tipo contenedor) no son significativos en las clases estáticas.
  • Reemplace el símbolo de operador no válido por un operador sobrecargable válido (CS1037). Solo se pueden sobrecargar operadores específicos definidos por el lenguaje.
  • Corrija la sintaxis para seguir el formulario del operador de conversión necesario: public static implicit operator <dest-type>(<source-type> parameter) o public static explicit operator <dest-type>(<source-type> parameter) (CS1553). El compilador espera que los operadores de conversión sigan un patrón de declaración específico.

Para ver errores relacionados con implementaciones de interfaz explícitas de operadores en interfaces estáticas abstractas, consulte Errores de miembros de interfaces estáticas, abstractas y virtuales.

Accesibilidad incoherente

  • CS0056: Accesibilidad incoherente: el tipo de valor devuelto 'type' es menos accesible que el operador 'operator'.
  • CS0057: Accesibilidad incoherente: el tipo de parámetro 'type' es menos accesible que el operador 'operator'.

Todos los tipos usados en la firma de un operador público deben ser al menos tan accesibles como el propio operador. Para obtener las reglas completas, consulte Modificadores de acceso y restricciones de accesibilidad en la especificación de C#.

  • Cambie el tipo de retorno a un tipo al menos tan accesible como el operador, o reduzca la accesibilidad del operador para que coincida con el tipo de retorno (CS0056). Un public operador no puede exponer un tipo menos accesible a través de su valor devuelto porque los llamadores fuera del ensamblaje no podrían usar el resultado.
  • Cambie el tipo de parámetro a un tipo al menos tan accesible como operador, o reduzca la accesibilidad del operador para que coincida con el tipo de parámetro (CS0057). Un public operador no puede requerir un tipo menos accesible como parámetro porque los llamadores fuera del assembly no podrían proporcionar el argumento.

Restricciones de conversión definidas por el usuario

  • CS0552: conversión definida por el usuario a o desde la interfaz.
  • CS0553: conversión definida por el usuario a o desde la clase base.
  • CS0554: conversión definida por el usuario a o desde la clase derivada.
  • CS0555: El operador definido por el usuario no puede tomar un objeto del tipo envolvente y convertirlo en un objeto del tipo envolvente.
  • CS0556: La conversión definida por el usuario debe convertir hacia o desde el tipo envolvente.
  • CS0557: Conversión duplicada definida por el usuario en el tipo .

El lenguaje C# restringe los tipos que pueden participar en conversiones definidas por el usuario. Para obtener las reglas completas, consulte Operadores de conversión definidos por el usuario y Operadores de conversión en la especificación de C#.

  • Quite el operador de conversión que convierte en o desde un tipo de interfaz (CS0552). Este lenguaje prohíbe las conversiones definidas por el usuario que implican tipos de interfaz porque las conversiones de interfaz se gestionan mediante las conversiones de referencia y encapsulación del sistema de tipos de referencia. En su lugar, use implementaciones de interfaz explícitas o métodos auxiliares.
  • Quite el operador de conversión que convierte en o desde una clase base (CS0553). Las conversiones entre un tipo y su clase base ya existen a través de conversiones de referencia implícitas (conversión ascendente) y conversiones de referencia explícitas (conversión descendente), por lo que una conversión definida por el usuario crearía ambigüedad.
  • Quite el operador de conversión que convierte a o de una clase derivada (CS0554). Al igual que las conversiones de clases base, las conversiones entre un tipo y sus tipos derivados se integran en el lenguaje a través de la herencia y las conversiones definidas por el usuario entrarían en conflicto con ellos.
  • Quite el operador de conversión que convierte el tipo envolvente en sí mismo (CS0555). Cada tipo ya tiene una conversión de identidad implícita a sí misma, por lo que una conversión definida por el usuario de un tipo al mismo tipo es redundante y no se permite.
  • Cambie uno de los tipos del operador de conversión para que el tipo de origen o de destino sea el tipo envolvente (CS0556). Una conversión definida por el usuario debe implicar el tipo que lo declara: no se puede definir una conversión entre dos tipos externos no relacionados en un tercer tipo.
  • Quite el operador de conversión duplicado o cambie uno de los operadores duplicados, por lo que los tipos de origen y destino difieren del otro (CS0557). Un tipo solo puede declarar una conversión implícita y explícita para cualquier par determinado de tipos de origen y destino.

Operadores booleanos y de cortocircuito

  • CS0215: el tipo de valor devuelto del operador true o false debe ser bool.
  • CS0216: el operador requiere que también se defina un operador coincidente.
  • CS0217: para poder aplicarse como operador de cortocircuito, un operador lógico definido por el usuario debe tener el mismo tipo de valor devuelto que el tipo de sus 2 parámetros.
  • CS0218: el tipo debe contener declaraciones del operador true y el operador false.

El lenguaje C# requiere emparejamientos y firmas específicos para operadores booleanos y evaluación de cortocircuito. Para obtener las reglas completas, vea operadores true y false, operadores lógicos booleanos y operadores lógicos condicionales definidos por el usuario en la especificación de C#.

  • Cambie el tipo de valor devuelto de operator true y operator false a bool (CS0215). Estos operadores determinan si un valor es lógico true o false, por lo que el lenguaje les exige que devuelvan bool.
  • Defina el operador emparejado coincidente (CS0216). El lenguaje requiere que determinados operadores se declaren en pares: operator == con operator !=, operator < con operator >, operator <= con operator >=y operator true con operator false.
  • Cambie el tipo de valor devuelto del operador & o | definido por el usuario para que coincida con ambos tipos de parámetros (CS0217). Para la evaluación de cortocircuito (&& y ||), el compilador requiere que el tipo de valor devuelto del operador & o |, los dos tipos de parámetros y el tipo del contenedor sean todos del mismo tipo.
  • Agregue tanto las declaraciones operator true como operator false al tipo (CS0218). El compilador vuelve a escribir && y || usando operator true, operator false, y el operador & o | correspondiente, por lo que los tres deben estar presentes para que funcione la evaluación de cortocircuito.

Operadores comprobados

  • CS9023: No se puede comprobar el operador
  • CS9024: El operador no se puede desactivar
  • CS9025: El operador Checked requiere que también se declare una versión no comprobada coincidente.
  • CS9027: palabra clave inesperada 'unchecked'

Las checked palabras clave y unchecked solo se pueden aplicar a declaraciones de operador específicas. Para obtener las reglas completas, consulte Operadores aritméticos y Operadores comprobados definidos por el usuario.

  • Quite la checked palabra clave o unchecked de un operador no admitido (CS9023, CS9024). Solo los operadores aritméticos +, , -*/++, --y los operadores de conversión explícitos admiten variantes activadas y desactivadas. Otros operadores, como los operadores de comparación o igualdad, no tienen un comportamiento de desbordamiento distinto y no se pueden marcar como activados o desactivados.
  • Agregue una versión no comprobada coincidente del operador (CS9025). Un checked operador proporciona el comportamiento de lanzamiento de desbordamiento, pero el compilador también necesita la versión no desactivada correspondiente para usarla en unchecked contextos y como valor predeterminado cuando no se especifica ningún contexto.
  • Quite la unchecked palabra clave de la posición no válida (CS9027). La unchecked palabra clave de una declaración de operador solo es válida como parte de la sintaxis del operador (por ejemplo, public static explicit operator unchecked int(MyType t)). Colocarlo en otro lugar de la declaración produce un error de sintaxis.

Requisitos de interfaz y herencia

  • CS9311: El tipo no implementa el miembro de interfaz. El tipo no puede implementar un miembro porque uno de ellos no es un operador
  • CS9312: El tipo no puede invalidar el miembro heredado porque uno de ellos no es un operador
  • CS9313: El operador de asignación compuesta sobrecargado toma un parámetro

El compilador aplica una coincidencia estricta entre las declaraciones de operador y los miembros de interfaz o los miembros de clase base que implementan o invalidan. Para obtener las reglas completas, consulte Sobrecarga de operadores e interfaces.

  • Cambie el miembro de implementación a una declaración de operador que coincida con el miembro del operador de la interfaz o cambie el miembro de interfaz a un método si el miembro de implementación es un método (CS9311). Un operador solo puede implementar un miembro de interfaz que también se declara como operador: no se puede satisfacer un contrato de operador con un método normal o viceversa.
  • Cambie el miembro de invalidación a una declaración de operador que coincida con el miembro de operador de la clase base o cambie el miembro de clase base a un método si el miembro de clase derivada es un método (CS9312). Al igual que en la implementación de una interfaz, una sobrescritura debe coincidir con el tipo de miembro que se está sobrescribiendo; un operador no puede sobrescribir un miembro que no sea operador.
  • Cambie la declaración del operador de asignación compuesta para aceptar exactamente un parámetro (CS9313). Los operadores de asignación compuesta son miembros de instancia en los que el operando izquierdo es implícitamente this, por lo que solo el operando derecho se declara como parámetro.

Operadores de igualdad

  • CS0659: 'class' invalida Object.Equals(object o), pero no invalida Object.GetHashCode()
  • CS0660: El tipo define el operador == o el operador != pero no invalida Object.Equals(object o)
  • CS0661: El tipo define el operador == o el operador != pero no invalida Object.GetHashCode()

El compilador requiere que las invalidaciones relacionadas con la igualdad y las definiciones de operador permanezcan sincronizadas. Al invalidar Object.Equals o definir operator == / operator !=, también debe proporcionar las invalidaciones relacionadas. Para obtener las reglas completas, vea Cómo definir la igualdad de valores para un tipo y operadores de igualdad.

  • Agregue una invalidación de Object.GetHashCode al invalidar Object.Equals (CS0659). Las colecciones basadas en hash como Dictionary<TKey,TValue> y HashSet<T> se basan en el contrato que dos objetos iguales deben devolver el mismo código hash. Sin una invalidación coincidente GetHashCode , los objetos que se comparan como iguales podrían aplicar hash a diferentes cubos, lo que provoca que las búsquedas y la desduplicación produzcan errores de forma silenciosa.
  • Agregue una invalidación de Object.Equals al definir operator == o operator != (CS0660). El código que llama Equals directamente (incluidas muchas API de marco, métodos LINQ y operaciones de recopilación) no usará el operador personalizado. Sin una invalidación coherenteEquals, los mismos dos objetos pueden considerarse iguales por ==, pero no por Equals, lo que provoca un comportamiento impredecible.
  • Agregue una invalidación de Object.GetHashCode al definir operator == o operator != (CS0661). Al igual que CS0659, debe GetHashCode ser coherente con la semántica de igualdad. Si operator == considera que dos objetos son iguales, pero devuelven códigos hash diferentes, las colecciones basadas en hash no funcionarán correctamente.

Errores de desbordamiento y subdesbordamiento

  • CS0031: El valor constante 'value' no se puede convertir en un 'type'
  • CS0220: La operación se desborda en tiempo de compilación en modo comprobado
  • CS0221: El valor constante 'value' no se puede convertir en un 'type' (use la sintaxis 'unchecked' para invalidar)
  • CS0463: Error en la evaluación de la expresión constante decimal con error: 'error'
  • CS0543: 'enumeration': el valor del enumerador es demasiado grande para caber en su tipo
  • CS0594: La constante de punto flotante está fuera del rango del tipo 'type'
  • CS0652: La comparación con constante integral es inútil; la constante está fuera del intervalo de tipo 'type'
  • CS1021: la constante integral es demasiado grande
  • CS8778: el valor constante 'value' puede desbordar 'type' en tiempo de ejecución (use la sintaxis 'unchecked' para invalidar)
  • CS8973: La operación puede desbordarse en tiempo de ejecución (use la sintaxis "desactivada" para invalidar)

El compilador evalúa expresiones constantes en tiempo de compilación e informa de errores o advertencias cuando un valor supera el intervalo válido de su tipo de destino. Para consultar las reglas completas, vea instrucciones comprobadas y no comprobadas y tipos enteros.

  • Cambie el valor constante a uno que se ajuste al intervalo del tipo de destino o cambie el destino a un tipo numérico mayor (CS0031). El compilador no puede restringir implícitamente una constante que no se ajuste; por ejemplo, la asignación 256 a un byte (intervalo de 0 a 255) genera este error. Si el truncamiento es intencionado, utilice una conversión explícita en un contexto unchecked.
  • Corrija la aritmética en la expresión constante para que el resultado se ajuste al tipo de destino o envuelva la expresión en un contexto unchecked para permitir el desbordamiento silencioso (CS0220). El compilador evalúa la expresión constante completa en tiempo de compilación en un contexto comprobado de forma predeterminada, por lo que los resultados intermedios o finales que superan el intervalo del tipo provocan este error.
  • Cambie el valor constante o el tipo de destino para que la conversión sea válida o encapsula la expresión en un unchecked contexto si desea intencionadamente el resultado truncado (CS0221). A diferencia de CS0220, este error se aplica a conversiones constantes explícitas en las que el valor de origen no se ajusta al tipo de destino.
  • Simplifique o interrumpa la decimal expresión constante para que permanezca dentro del intervalo y la precisión del decimal tipo (CS0463). El decimal tipo tiene un valor máximo de aproximadamente $7,9 \times 10^{28}$ y 28–29 dígitos significativos, y el compilador evalúa la expresión completa en tiempo de compilación.
  • Cambie el valor del miembro de enumeración a uno que se ajuste al tipo subyacente de la enumeración o cambie el tipo subyacente a un tipo entero mayor (CS0543). De forma predeterminada, las enumeraciones usan int como tipo subyacente. Si el valor de un miembro supera el intervalo del tipo subyacente, especifique un tipo mayor como long.
  • Cambie la constante de punto flotante a un valor dentro del intervalo del tipo de destino o use un tipo de precisión superior, como double en lugar de float (CS0594). El float tipo admite valores de hasta $3,4 \times 10^{{38}}$, y double admite hasta $1,7 \times 10^{{308}}$.
  • Quite o corrija la comparación para que la constante esté dentro del intervalo del tipo de la variable (CS0652). Comparar una byte variable con 300, por ejemplo, nunca puede ser true, por lo que el compilador advierte de que la comparación es inútil. Esta advertencia suele indicar un error lógico o una discrepancia entre el tipo de variable y el intervalo de valores previsto.
  • Use un tipo numérico mayor o divida el valor en varias operaciones (CS1021). Este error se produce cuando un literal entero sobrepasa el rango del tipo integral más grande (ulong, hasta $1,8 \times 10^{19}$). Para los valores más allá de ese intervalo, considere la posibilidad de usar BigInteger.
  • Envuelva la expresión en un unchecked contexto para suprimir la advertencia, o cambie el valor para que se ajuste al rango del tipo de destino (CS8778). Esta advertencia indica una conversión constante que podría perder datos en tiempo de ejecución: el compilador no puede demostrar que el desbordamiento se producirá definitivamente, pero identifica el riesgo.
  • Encierre la expresión en un contexto unchecked para suprimir la advertencia o reestructure la aritmética para evitar un posible desbordamiento (CS8973). Esta advertencia es similar a CS8778, pero se aplica a operaciones aritméticas en lugar de conversiones: el compilador detecta que la operación puede desbordarse en tiempo de ejecución.