2009-11-17 14 views
6

¿El término devolución de llamada en el contexto de delegados significa, "un delegado delegando que funciona a otro delegado para completar alguna tarea"?Delegados y devoluciones de llamada

Ejemplo :(Basado en mi conocimiento, he implementado una devolución de llamada, corrígeme si está mal)

namespace Test 
{ 
    public delegate string CallbackDemo(string str); 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      CallbackDemo handler = new CallbackDemo(StrAnother); 
      string substr = Strfunc(handler); 
      Console.WriteLine(substr); 
      Console.ReadKey(true); 
     } 

     static string Strfunc(CallbackDemo callback) 
     { 
      return callback("Hello World"); 
     } 

     static string StrAnother(string str) 
     { 
      return str.Substring(1, 3).ToString(); 
     } 
    } 
} 

Sírvanse proporcionar ejemplos como sea necesario.

+1

Merece la pena pensar en un delegado como un tipo que es un puntero a un método: como una interfaz o una clase: es una plantilla para una instancia que es en sí misma una referencia a su método interno: la instancia se puede pasar entre objetos e invocado/ejecutado en cualquier momento. Si tiene alguna forma de hacerse con "C# en profundidad" por Jon Skeet y leer la sección del capítulo 2 sobre Delegados y el Capítulo 5 sobre Delegados, entenderemos la "evolución" de los delegados de su "larva" etapa "en C# 1.0, a su forma totalmente" evolucionada "en C# 3.0. Nunca he encontrado una mejor exposición – BillW

Respuesta

11

Su ejemplo es un buen comienzo, pero es incorrecto. No se crea un nuevo delegado en el método, se usa en la declaración de un evento en la clase. Vea este ejemplo modificado de su código:

namespace Test 
{ 
    //In this case, this delegate declaration is like specifying a specific kind of function that must be used with events. 
    public delegate string CallbackDemo(string str); 
    class Program 
    { 
     public static event CallbackDemo OnFoobared; 
     static void Main(string[] args) 
     { 
      //this means that StrAnother is "subscribing" to the event, in other words it gets called when the event is fired 
      OnFoobared += StrAnother; 
      string substr = Strfunc(); 
      Console.WriteLine(substr); 
      Console.ReadKey(true); 
      //this is the other use of delegates, in this case they are being used as an "anonymous function". 
      //This one takes no parameters and returns void, and it's equivalent to the function declaration 
      //'void myMethod() { Console.WriteLine("another use of a delegate"); }' 
      Action myCode = delegate 
      { 
       Console.WriteLine("another use of a delegate"); 
      }; 
      myCode(); 
      Console.ReadKey(true); 
      //the previous 4 lines are equivalent to the following however this is generally what you should use if you can 
      //its called a lambda expression but it's basically a way to toss arbitrary code around 
      //read more at http://www.developer.com/net/csharp/article.php/3598381/The-New-Lambda-Expressions-Feature-in-C-30.htm or 
      //http://stackoverflow.com/questions/167343/c-lambda-expression-why-should-i-use-this 
      Action myCode2 =() => Console.WriteLine("a lambda expression"); 
      myCode2(); 
      Console.ReadKey(true); 
     } 

     static string Strfunc() 
     { 
      return OnFoobared("a use of a delegate (with an event)"); 
     } 
     static string StrAnother(string str) 
     { 
      return str.Substring(1, 3).ToString(); 
     } 
    } 
} 

Solo he arañado la superficie aquí; desbordamiento de pila de búsqueda para "delegar C#" y "expresión lambda C#" para mucho más!

+0

Muchas gracias – user160677

+0

¡De nada! – RCIX

3

Una devolución de llamada es básicamente un delegado pasado a un procedimiento que ese procedimiento "devolverá la llamada" en algún punto apropiado. Por ejemplo, en llamadas asincrónicas como WebRequest.BeginGetResponse o una operación WCF BeginXxx, pasaría una AsyncCallback. El trabajador "devolverá la llamada" al método que ingrese como AsyncCallback, en este caso, cuando haya terminado, para informarle que ha finalizado y para obtener el resultado.

Un controlador de eventos podría considerarse otro ejemplo. Por ejemplo, cuando conecta un controlador a un evento Click, el botón "devolverá la llamada" a ese controlador cuando se produce el clic.

3

Una devolución de llamada es lo que el delegado ejecuta cuando se invoca. Por ejemplo, cuando se utiliza el modelo asincrónico utilizando los delegados, que haría algo como esto:

public static void Main(string[] args) 
{ 
    Socket s = new Socket(...); 

    byte[] buffer = new byte[10]; 
    s.BeginReceive(buffer, 0, 10, SocketFlags.None, new AsyncCallback(OnMessageReceived), buffer); 

    Console.ReadKey(); 
} 

public static void OnMessageReceived(IAsyncResult result) 
{ 
    // ... 
} 

OnMessageReceived es la devolución de llamada, el código que se ejecuta mediante la invocación del delegado. Consulte this Wikipedia article para obtener más información o Google algunos ejemplos más.

1

Esto se votará precisamente por la razón por la cual es correcto. C# no implementa delegados, lo que implementa es reenvío de llamadas. Este uso incorrecto de la nomenclatura es probablemente el mayor problema con C# en este sentido.

El siguiente documento de ACM es la primera descripción de lo que más tarde se llamaría un delegado. Básicamente, un delegado es algo que parece ser una instancia de un objeto (la forma en que se implementa realmente es irrelevante). Esto significa que puede llamar a métodos, propiedades de acceso, etc. desde el delegado.

http://web.media.mit.edu/~lieber/Lieberary/OOP/Delegation/Delegation.html

Lo que C# es implementos devoluciones de llamada o de desvío de llamadas (todo depende de la forma de usarlos). Estos no son delegados. Para ser un delegado uno puede acceder al objeto como si fuera el objeto mismo.

Cuando un bolígrafo delega un mensaje de dibujo en un bolígrafo prototípico, significa "No sé cómo manejar el mensaje de dibujo. Me gustaría que me lo contestes si puedes, pero si tienes más preguntas, como cuál es el valor de mi variable x, o si necesitas hacer algo, deberías volver y preguntar ". Si el mensaje se delega aún más, todas las preguntas sobre los valores de las variables o las solicitudes de respuesta a los mensajes se infieren al objeto que delegó el mensaje en primer lugar.- Henry Lieberman

Entonces, ¿cómo se estropeó? Para ser honesto, no sé. SÉ que sé que he estado usando delegados (hace más de 16 años) mucho antes de C# y los implementos de C# no son delegados.

Aquí puede encontrar una explicación muy buena.

http://www.saturnflyer.com/blog/jim/2012/07/06/the-gang-of-four-is-wrong-and-you-dont-understand-delegation/

delegación real es más que la creación de devoluciones de llamada o el desvío de llamadas. Un delegado real me permite llamar a cualquier método en ese objeto, obtener y/o establecer propiedades públicas, etc., todo como si fuera el objeto mismo. Esto es mucho más poderoso y realmente más fácil de usar que la "delegación" de C#.

El PO preguntó:

¿La devolución de llamada término en el contexto de los delegados decir, "un delegado delegar funciona a otro delegado finde para terminar alguna tarea"?

La respuesta a esto es sí. Una devolución de llamada en el contexto de delegados puede solo puede ser utilizada para finalizar alguna tarea. Por ejemplo, tienes una clase que obtiene datos de un sitio meteorológico. Como no es determinista, implementar una devolución de llamada cuando los datos se han recibido (y tal vez analizado) sería espectacular.

En cuanto a por qué se corrompió la delegación, no tengo ni idea. Espero que C# implemente la delegación VERDADERA.

+0

Abajo votado porque ...? –

Cuestiones relacionadas