2012-03-29 12 views
57

Fondamentalmente sto provando a passare un metodo a un'altra classe per essere chiamato più tardi, ma non riesco a capirlo in C# (sono ancora troppo abituato a Objective-C).Passare una funzione di richiamata a un'altra classe

public class Class1{ 

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

    public void myCallback(string str) 
    { 
    } 
} 

poi in seguito voglio che la mia classe ServerRequest al fuoco fondamentalmente la funzione di callback, è questo non è possibile? (In pratica sto telefonando a un server per una risposta di accesso al mio software)

Non sono riuscito a trovare un modo per farlo con i delegati, ottenendo continuamente errori. Ecco l'altra classe:

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

È possibile in #? In Objective-C questo sarebbe semplice e vorrei solo fare qualcosa di simile

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

risposta

99

È possibile passare come Action<string> - che significa che è un metodo con un solo parametro di tipo string che non restituisce nulla (void):

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

così semplice, grazie! Non avevo idea di Action! – Geesu

+0

E come si chiama DoRequest? Passi una stringa o un metodo? – Kokodoko

+0

per altri curiosi sull'azione. ecco un consiglio veloce si può avere più parms tipo, ma non ritorno (per il passaggio di C# membri solo Azione non permette modificatore sui tipi Per passare la funzione, utilizzare Func ancora alcun modificatore su qualsiasi tipo la l'ultimo tipo nella lista è la funzione tipo di ritorno in realtà Action e Func sono un modo rapido per utilizzare delegati semplici – gg89

9

si deve dichiarare prima tipologia del delegato, perché i delegati sono fortemente tipizzati:

public void MyCallbackDelegate(string str); 

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

Questa è un'ottima soluzione se stai utilizzando lo stesso metodo di firma in molti luoghi nel codice. – mtmurdock

+3

È consigliabile controllare sempre se il metodo di callback non è nullo prima di chiamarlo. –

3

Delegate è solo il classe base in modo da non poterlo usare così. Si potrebbe fare qualcosa di simile a questo, però:

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

'Func ' sarebbe un metodo che * restituisce * a str ing - hai bisogno di un 'Action ' – BrokenGlass

+0

@BrokenGlass hai ragione mio male - aggiornato (ho + 1d la tua risposta) – Robbie

3

è possibile modificare il codice in questo modo:

public delegate void CallbackHandler(string str); 

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

Quello che vi serve è un delegato e un callback. Here è un bell'articolo MSDN che ti mostrerà come utilizzare questa tecnica in 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

grazie per questo dettagliato esempio – gdbj

Problemi correlati