c# - programacion - el metodo no tiene una firma compatible con el delegado
¿Los delegados no son solo interfaces abreviadas? (10)
Desde la perspectiva de Ingeniería de Software, tiene razón, los delegados se parecen mucho a las interfaces de funciones, ya que diseñan una interfaz de función.
También se pueden usar de la misma manera: en lugar de pasar toda una clase que contiene el método que necesita, puede pasar solo como delegado. Esto ahorra una gran cantidad de código y crea un código mucho más legible.
Además, con la llegada de las expresiones lambda, ahora también se pueden definir fácilmente al vuelo, lo que es una gran ventaja. Si bien es POSIBLE construir clases sobre la marcha en C #, es realmente un gran dolor en el trasero.
Comparar los dos es un concepto interesante. No había considerado anteriormente lo parecidas que son las ideas desde un punto de vista de uso y estructuración de código.
Supongamos que tenemos:
interface Foo
{
bool Func(int x);
}
class Bar: Foo
{
bool Func(int x)
{
return (x>0);
}
}
class Baz: Foo
{
bool Func(int x)
{
return (x<0);
}
}
Ahora podemos lanzar Bar and Baz como un Foos y llamar a sus métodos Func.
Los delegados simplifican esto un poco:
delegate bool Foo(int x);
bool Bar(int x)
{
return (x<0);
}
bool Baz(int x)
{
return (x>0);
}
Ahora podemos lanzar a Bar y Baz como delegados de Foo.
¿Cuál es el beneficio real de los delegados, a excepción de obtener un código más corto?
Las interfaces y los delegados son dos cosas completamente diferentes, aunque entiendo la tentación de describir a los delegados en términos de interfaz para facilitar la comprensión ... sin embargo, no saber la verdad puede llevar a confusión en el futuro.
Los delegados se inspiraron (en parte) debido a que el arte negro de los punteros del método C ++ era inadecuado para ciertos propósitos. Un ejemplo clásico es la implementación de un mecanismo de paso de mensajes o manejo de eventos. Los delegados le permiten definir una firma de método sin ningún conocimiento de los tipos o interfaces de una clase: podría definir un delegado "void eventHandler (Event * e)" e invocarlo en cualquier clase que lo implemente.
Para una idea de este problema clásico, y por qué los delegados son deseables, lea esto y luego esto .
No, los delegados son para punteros de método. Entonces puede asegurarse de que la firma del método asociado con el delegado sea correcta.
Además, entonces no necesitas saber la estructura de la clase. De esta forma, puede usar un método que haya escrito para pasar a un método en otra clase, y definir la funcionalidad que desea que suceda.
Eche un vistazo a la clase List <> con el método Find . Ahora puede definir qué determina si algo es una coincidencia o no, sin requerir que los elementos contenidos en la clase implementen IListFindable o algo similar.
Puede pasar delegados como parámetros en funciones (Ok, técnicamente los delegados se convierten en objetos cuando se compilan, pero ese no es el punto aquí). Puede pasar un objeto como parámetro (obviamente), pero luego está vinculando ese tipo de objeto a la función como parámetro. Con los delegados puede pasar cualquier función para ejecutar en el código que tiene la misma firma, independientemente de dónde provenga.
Sí, un delegado puede considerarse una interfaz con un método.
Un delegado comparte mucho en común con una referencia de interfaz que tiene un único método desde el punto de vista de la persona que llama.
En el primer ejemplo, Baz y Bar son clases, que se pueden heredar e instanciar. En el segundo ejemplo, Baz y Bar son métodos.
No puede aplicar referencias de interfaz a cualquier clase que coincida con el contrato de interfaz. La clase debe declarar explícitamente que es compatible con la interfaz. Puede aplicar una referencia de delegado a cualquier método que coincida con la firma.
No puede incluir métodos estáticos en el contrato de una interfaz. (Aunque puede atornillar métodos estáticos con métodos de extensión). Puede referirse a métodos estáticos con una referencia de delegado.
Un delegado es un puntero de método tipeado. Esto le da más flexibilidad que las interfaces porque puede aprovechar la covarianza y la contravarianza, y puede modificar el estado del objeto (tendría que pasar este puntero con funtores basados en la interfaz).
Además, los delegados tienen mucha azúcar sintáctica agradable que te permite hacer cosas como combinarlas fácilmente.
Uno puede pensar en los delegados como una interfaz para un método que define qué argumentos y qué tipo de retorno debe tener un método para adaptarse al delegado.
Hay una ligera diferencia, los delegados pueden acceder a las variables miembro de las clases en las que están definidas. En C # (a diferencia de Java), todas las clases internas se consideran estáticas. Por lo tanto, si está utilizando una interfaz para administrar una devolución de llamada, por ejemplo, un ActionListener para un botón. La clase interna de implementación necesita pasar (a través del constructor) referencias a las partes de la clase contenedora con las que puede necesitar interactuar durante la devolución de llamada. Los delegados no tienen esta restricción, por lo tanto, reduce la cantidad de código requerido para implementar la devolución de llamada.
Un código más breve y conciso también es un beneficio digno.
En al menos una propuesta para agregar cierres (es decir, delegados anónimos) a Java, son equivalentes a las interfaces con un método de miembro único.