Resolver errores y advertencias para delegados y punteros de función

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

  • CS0059: Accesibilidad incoherente: el tipo de parámetro 'type' es menos accesible que el delegado 'delegate'.
  • CS0123: Ninguna sobrecarga de "method" coincide con el delegado "delegate".
  • CS0148: el delegado 'delegate' no tiene un constructor válido.
  • CS0410: Ninguna sobrecarga de "método" tiene los tipos de parámetro y de retorno correctos.
  • CS0644: 'class' no puede derivar de la clase especial 'class'.
  • CS1599: el tipo de valor devuelto de un puntero de método, delegado o función no puede ser 'type'.
  • CS1958: es posible que las expresiones de inicializador de objeto y colección no se apliquen a una expresión de creación de delegados.
  • CS8755: 'modificador' no se puede usar como modificador en un parámetro de puntero de función.
  • CS8756: El puntero a función "type" no admite "count" argumentos.
  • CS8757: No hay ninguna sobrecarga para 'method' que coincida con el puntero de función 'type'.
  • CS8758: error de coincidencia de referencia entre 'method' y el puntero de función 'type'.
  • CS8759: no se puede crear un puntero de función para 'method' porque no es un método estático.
  • CS8786: La convención de llamada de 'convention' no es compatible con 'convention'.
  • CS8787: No se puede convertir el grupo de métodos al puntero de función. (¿Faltas un '&'?)
  • CS8788: No se puede usar un método de extensión con un receptor como destino de un operador '&'.
  • CS8789: el tipo de un local declarado en una instrucción fija no puede ser un tipo de puntero de función.
  • CS8806: el lenguaje no admite la convención de llamada de "convención".
  • CS8807: 'specifier' no es un especificador de convención de llamada válido para un puntero de función.
  • CS8808: 'modificador' no es un modificador válido del tipo de retorno de un puntero de función. Los modificadores válidos son "ref" y "ref readonly".
  • CS8809: Un tipo de retorno solo puede tener un modificador "modifier".
  • CS8811: No se puede convertir el grupo de métodos 'method' al tipo delegado 'type'.
  • CS8909: la comparación de punteros de función puede producir un resultado inesperado, ya que los punteros a la misma función pueden ser distintos.
  • CS8911: no se admite el uso de un tipo de puntero de función en este contexto.

Discrepancia en la firma del delegado

  • CS0059: Accesibilidad incoherente: el tipo de parámetro 'type' es menos accesible que el delegado 'delegate'.
  • CS0123: Ninguna sobrecarga de "method" coincide con el delegado "delegate".
  • CS0148: el delegado 'delegate' no tiene un constructor válido.
  • CS0410: Ninguna sobrecarga de "método" tiene los tipos de parámetro y de retorno correctos.

Al crear o asignar un delegado, el compilador comprueba que la firma del método de destino coincide con la declaración del tipo delegado. La firma incluye los tipos de parámetro, el tipo de valor devuelto y la accesibilidad. Para obtener las reglas completas, consulte Delegados y restricciones de accesibilidad en la especificación de C#.

  • Cambie todos los tipos de parámetro de la declaración de delegado a tipos que sean al menos tan accesibles como el propio delegado (CS0059). Un public delegado no puede hacer referencia a un tipo menos accesible en su lista de parámetros, ya que los llamantes externos al ensamblado no podrían proporcionar el argumento. Para obtener más información, vea Modificadores de acceso.
  • Ajuste la firma del método o la firma del delegado para que los tipos de parámetro y el tipo de valor devuelto coincidan exactamente (CS0123). El compilador requiere una coincidencia exacta de firma al asignar un método a un delegado.
  • Comprueba que el delegado haya sido compilado por un compilador conforme (CS0148). Este error se produce al importar un ensamblado administrado compilado por un compilador que produjo un constructor delegado con formato incorrecto. Vuelva a compilar el ensamblado con un compilador compatible con estándares para resolver el error.

Note

El compilador de C# actual ya no genera CS0410. Ahora, la misma condición genera CS0123 en su lugar. Los ensamblados más antiguos compilados con compiladores anteriores podrían seguir teniendo referencia a este código de error.

CS0148 es un diagnóstico exclusivo de la compilación:

Note

Esta advertencia solo se notifica durante las operaciones explícitas de compilación o recompilación . No aparece mientras se escribe en el IDE como parte de los diagnósticos de IntelliSense. Esto significa que, si corrige la advertencia utilizando el campo o eliminándolo, la advertencia podría persistir en la lista de errores hasta que compile o vuelva a compilar el proyecto.

Restricciones de tipo de delegado

  • CS0644: 'class' no puede derivar de la clase especial 'class'.
  • CS1599: El tipo de retorno de un método, delegado o puntero de función no puede ser 'type'.
  • CS1958: es posible que las expresiones de inicializador de objeto y colección no se apliquen a una expresión de creación de delegados.

El lenguaje C# restringe cómo puede usar determinados tipos especiales, incluido System.Delegate. Para obtener las reglas completas sobre declaraciones de delegados, vea Delegados y delegados en la especificación de C#.

  • Quite la clase base explícita y use una delegate declaración en su lugar (CS0644). Las clases no pueden heredar explícitamente de System.Delegate, System.Enum, System.ValueTypeo System.Array. El compilador usa estos tipos como clases base implícitas. Por ejemplo, cada delegate declaración deriva implícitamente de System.Delegate.
  • Cambie el tipo de valor devuelto a un tipo permitido como valor devuelto (CS1599). Algunos tipos de la biblioteca de clases de .NET, como TypedReference, RuntimeArgumentHandle y ArgIterator, no se pueden usar como tipos de valor devuelto para métodos, delegados o punteros de función porque pueden habilitar operaciones de pila no seguras.
  • Elimine las llaves después de la expresión de creación del delegado (CS1958). Los delegados no tienen miembros que se puedan establecer mediante la sintaxis de inicialización de objetos o colecciones. Si tiene { } después de una expresión new DelegateType(method), elimine las llaves.

Discrepancias en la firma del puntero a función

  • CS8755: 'modificador' no se puede usar como modificador en un parámetro de puntero de función.
  • CS8756: El puntero a función "type" no admite "count" argumentos.
  • CS8757: No hay sobrecarga para "method" que coincida con el puntero a función "type".
  • CS8758: error de coincidencia de referencia entre 'method' y el puntero de función 'type'.
  • CS8759: no se puede crear un puntero de función para 'method' porque no es un método estático.
  • CS8787: No se puede convertir el grupo de métodos al puntero de función. (¿Faltas un '&'?)
  • CS8788: No se puede usar un método de extensión con un receptor como destino de un operador '&'.
  • CS8811: No se puede convertir el grupo de &métodos 'method' al tipo delegado 'type'.

Al asignar un método a un puntero de función mediante el operador address-of (&), el compilador comprueba que la firma del método coincide con el tipo de puntero de función. Para obtener las reglas completas sobre las declaraciones y el uso del puntero de función, consulte Punteros de función y código no seguro.

  • Quite el modificador no admitido del parámetro de puntero de función (CS8755). Los parámetros de puntero de función admiten solo los modificadores ref, out y in. Otros modificadores de parámetro, como params, no son válidos en las declaraciones de tipo de puntero de función.
  • Cambie el número de argumentos del sitio de llamada para que coincida con el recuento de parámetros del puntero de función (CS8756). El tipo de puntero de función define un número fijo de parámetros, y debe pasar exactamente esa cantidad de argumentos.
  • Ajuste la firma del método para que sus tipos de parámetros, tipo de valor devuelto y recuento de parámetros coincidan con el tipo de puntero de función (CS8757). A diferencia de los delegados, los punteros de función no admiten conversiones implícitas entre firmas de método compatibles. La coincidencia debe ser exacta.
  • Alinee los refmodificadores , outo in entre los parámetros del método y los parámetros del tipo de puntero de función (CS8758). El tipo ref de cada parámetro debe coincidir exactamente. Un parámetro ref no puede satisfacer una posición in o out en el tipo de puntero de función.
  • Cambie el método de destino a static (CS8759). Los punteros de función solo pueden apuntar a métodos estáticos porque representan direcciones de funciones en bruto sin una instancia de objeto asociada.
  • Agregue el operador & antes del grupo de métodos al asignar a un puntero de función (CS8787). A diferencia de los delegados, los punteros de función requieren el operador de dirección explícito: delegate*<void> ptr = &MyMethod;.
  • Use un método estático en lugar de un método de extensión con un receptor (CS8788). El & operador requiere una referencia de método directo. Los métodos de extensión invocados en una instancia tienen un receptor implícito que no se puede capturar en un puntero a función.
  • Elimine el operador & y utilice en su lugar la sintaxis de delegado, o cambie el tipo de destino de un delegado a un puntero a función (CS8811). El & operador genera un puntero de función, no un delegado. Para asignar un grupo de métodos a un tipo delegado, omita el & y use la sintaxis de creación de delegados estándar.

Convenciones de llamada y tipos de retorno de punteros a función

  • CS8786: La convención de llamada "convention" no es compatible con "convention".
  • CS8806: el lenguaje no admite la convención de llamada de "convención".
  • CS8807: 'specifier' no es un especificador de convención de llamada válido para un puntero de función.
  • CS8808: 'modificador' no es un modificador de tipo de retorno para punteros de función válido. Los modificadores válidos son 'ref' y 'ref readonly'.
  • CS8809: Un tipo de retorno solo puede tener un modificador "modifier".

Las declaraciones de punteros a funciones incluyen una convención de llamada y modificadores opcionales del tipo de retorno. El compilador valida estas opciones. Para obtener las reglas completas, consulte Punteros de función.

  • Cambie la convención de llamada del método o la convención de llamada del tipo de puntero de función para que coincidan (CS8786). Al asignar un método a un puntero de función, las convenciones de llamada deben ser compatibles. Por ejemplo, un método que usa Cdecl no se puede asignar a un puntero de función declarado con Stdcall.
  • Use una convención de llamada admitida en la declaración del puntero de función (CS8806). El idioma admite managed y unmanaged. Para una convención no administrada específica, use la palabra clave con la unmanaged convención entre corchetes, como unmanaged[Cdecl], unmanaged[Stdcall], unmanaged[Thiscall]o unmanaged[Fastcall].
  • Reemplace el especificador no válido por una convención de llamada admitida (CS8807). Use managed, unmanagedo unmanaged con un tipo de convención de llamada entre corchetes (por ejemplo, unmanaged[Cdecl]).
  • Use solo ref o ref readonly como modificador de tipo de valor devuelto (CS8808). Otros modificadores, como out o in, no son válidos para los tipos devueltos de puntero de función.
  • Quite el modificador de tipo de retorno duplicado para que solo aparezca uno ref o ref readonly (CS8809). El compilador permite como máximo un modificador de tipo de retorno en una declaración de puntero de función.

Restricciones de uso del puntero de función

  • CS8789: el tipo de un local declarado en una instrucción fija no puede ser un tipo de puntero de función.
  • CS8909: la comparación de punteros de función puede producir un resultado inesperado, ya que los punteros a la misma función pueden ser distintos.
  • CS8911: no se admite el uso de un tipo de puntero de función en este contexto.

El compilador restringe cómo se pueden usar los tipos de puntero de función en determinados contextos. Para obtener las reglas completas, consulte Punteros de función.

  • Cambie el tipo de variable local de la fixed instrucción a un tipo de puntero de datos en lugar de un tipo de puntero de función (CS8789). La fixed instrucción ancla objetos administrados en memoria para el acceso a datos. Los punteros de función representan direcciones de código, no datos y no se pueden anclar.
  • Evite comparar punteros a funciones para comprobar si son iguales (CS8909). Esta advertencia indica que la comparación de punteros de función con == o != podría generar resultados inesperados. El tiempo de ejecución puede devolver punteros diferentes para la misma función debido a detalles de implementación, como el thunking o la compilación JIT. Para suprimir la advertencia cuando confirme que la comparación es intencionada, use #pragma warning disable CS8909.
  • Mueva el uso del puntero de función a un contexto admitido (CS8911). Los tipos de puntero de función no se pueden usar en determinadas posiciones, como en argumentos de atributo o expresiones typeof. Reestructure el código para evitar el uso de tipos de puntero de función en contextos no admitidos.