2012-03-29 25 views
57

Básicamente trato de pasar un método a otra clase para llamarlo más tarde, pero no puedo entenderlo en C# (todavía estoy demasiado acostumbrado a Objective-C).Pasando una función de devolución de llamada a otra clase

public class Class1{ 

    private void btn_click(object sender, EventArgs e) 
    { 
     ServerRequest sr = new ServerRequest(); 
     sr.DoRequest("myrequest", myCallback); 
    } 

    public void myCallback(string str) 
    { 
    } 
} 

Luego, más tarde Quiero mi clase ServerRequest al fuego, básicamente, la función de devolución de llamada, es posible que esto no? (Básicamente, llamo a casa a un servidor para obtener una respuesta de inicio de sesión a mi software)

No he podido encontrar la manera de hacer esto con los delegados, continuamente obtengo errores. Aquí está la otra clase:

public class ServerRequest 
{ 
    public void DoRequest(string request, Delegate callback) 
    { 
     // do stuff.... 
     callback("asdf"); 
    } 
} 

¿Es esto posible en #? En Objective-C este sería simple y que acaba de hacer algo como

[myObject performSelector(@selector(MyFunctionName)) withObjects:nil]; 

Respuesta

99

Puede pasarlo como Action<string> - lo que significa que es un método con un solo parámetro de tipo string que no devuelve nada (void):

public void DoRequest(string request, Action<string> callback) 
{ 
    // do stuff.... 
    callback("asdf"); 
} 
+1

tan simple gracias! ¡No tenía idea sobre Acción! – Geesu

+0

¿Y cómo llama a DoRequest? ¿Pasas una cuerda o un método? – Kokodoko

+0

para otros curiosos sobre Acción. aquí hay un consejo rápido. que puede tener múltiples parms tipo, pero no retorno (para pasar de C# sólo los miembros Acción no permite modificador de tipos Pasar función, utilice Func nuevo sin modificador en cualquier tipo la el último tipo en la lista es la función return type en realidad Action y Func son una forma rápida de usar delegados sencillos – gg89

9

Usted tiene que declarar primer tipo de delegado, porque los delegados son fuertemente tipados:

public void MyCallbackDelegate(string str); 

public void DoRequest(string request, MyCallbackDelegate callback) 
{ 
    // do stuff.... 
    callback("asdf"); 
} 
+0

Esta es una gran solución si usa la misma firma de método en muchos lugares en su código. – mtmurdock

+3

Es una buena práctica comprobar siempre si el método de devolución de llamada no es nulo antes de llamarlo. –

3

Delegate es sólo el clase base, así que no puedes usarlo así. Se podría hacer algo como esto, sin embargo:

public void DoRequest(string request, Action<string> callback) 
{ 
    // do stuff.... 
    callback("asdf"); 
} 
+1

'Func ' sería un método que * devuelve * una cadena ing - necesitas una 'Acción ' – BrokenGlass

+0

@BrokenGlass tienes razón, mi mal - actualizado (tengo + 1d tu respuesta) – Robbie

3

usted podría cambiar su código de esta manera:

public delegate void CallbackHandler(string str); 

public class ServerRequest 
{ 
    public void DoRequest(string request, CallbackHandler callback) 
    { 
     // do stuff.... 
     callback("asdf"); 
    } 
} 
2

Lo que se necesita es un delegado y una devolución de llamada. Here es un buen artículo de MSDN que le mostrará cómo usar esta técnica en C#.

17
public class Class1 
    { 

     private void btn_click(object sender, EventArgs e) 
     { 
      ServerRequest sr = new ServerRequest(); 
      sr.Callback += new ServerRequest.CallbackEventHandler(sr_Callback); 
      sr.DoRequest("myrequest"); 
     } 

     void sr_Callback(string something) 
     { 

     } 


    } 

    public class ServerRequest 
    { 
     public delegate void CallbackEventHandler(string something); 
     public event CallbackEventHandler Callback; 

     public void DoRequest(string request) 
     { 
      // do stuff.... 
      if (Callback != null) 
       Callback("bla"); 
     } 
    } 
+1

gracias por esta muestra detallada – gdbj

Cuestiones relacionadas