Übergabe einer Rückruffunktion an eine andere Klasse


90

Ich versuche im Grunde, eine Methode an eine andere Klasse zu übergeben, um sie später aufzurufen, kann dies aber in C # nicht ganz herausfinden (ich bin immer noch zu an Objective-C gewöhnt).

public class Class1{

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

    public void myCallback(string str)
    {
    }
}

Später möchte ich, dass meine ServerRequest-Klasse die Rückruffunktion grundsätzlich auslöst. Ist dies nicht möglich? (Grundsätzlich rufe ich einen Server an, um eine Anmeldeantwort für meine Software zu erhalten.)

Ich habe keinen Weg gefunden, dies mit Delegierten zu tun, und bekomme ständig Fehler. Hier ist die andere Klasse:

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

Ist das in # möglich? In Objective-C wäre das einfach und ich würde einfach so etwas tun

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

Antworten:


139

Sie können es als übergeben Action<string>- was bedeutet, dass es sich um eine Methode mit einem einzelnen Parameter vom Typ handelt string, die nichts zurückgibt (void):

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

Und wie nennt man DoRequest? Übergeben Sie eine Zeichenfolge oder eine Methode?
Kokodoko

1
für andere neugierig auf Action. Hier ist ein kurzer Tipp. Es kann mehrere Typparameter haben, aber keine Rückgabe (nur zum Übergeben von c # -Mitgliedern. Aktion <Typ1, .., TypN> erlaubt keinen Modifikator für Typen. Um die Funktion zu übergeben, verwenden Sie Func <Typliste> erneut. Kein Modifikator für einen Typ des letzten Typs in der Liste ist die Funktion Rückgabetyp tatsächlich Aktion und Func sind schnelle Möglichkeit, einfache Delegaten zu verwenden
gg89

Mach meinen Tag einfach und sauber!
Isanjosgon

24
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");
        }
    }

10

Sie müssen zuerst den Typ des Delegaten deklarieren, da die Delegierten stark typisiert sind:

public void MyCallbackDelegate( string str );

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

Dies ist eine großartige Lösung, wenn Sie an vielen Stellen in Ihrem Code dieselbe Methodensignatur verwenden.
Mtmurdock

4
Es wird empfohlen, vor dem Aufruf immer zu überprüfen, ob die Rückrufmethode nicht null ist.
Maciej

4

Delegateist nur die Basisklasse, also kannst du sie nicht so verwenden. Sie könnten jedoch so etwas tun:

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

2
Func<string>wäre eine Methode, die eine Zeichenfolge zurückgibt - Sie benötigen eineAction<string>
BrokenGlass

@BrokenGlass du hast recht mein schlechtes - aktualisiert (ich habe + 1d deine Antwort)
Robbie

3

Sie können Ihren Code folgendermaßen ändern:

public delegate void CallbackHandler(string str);

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

2

Was Sie brauchen, ist ein Delegierter und ein Rückruf. Hier ist ein schöner MSDN-Artikel, der Ihnen zeigt, wie Sie diese Technik in C # verwenden.


2

Sie können nur einen Delegaten verwenden, der für Rückruffunktionen am besten geeignet ist:

public class ServerRequest
{
    public delegate void CallBackFunction(string input);

    public void DoRequest(string request, CallBackFunction callback)
    {
        // do stuff....
        callback(request);
    }
}

und konsumiere dies wie folgt:

public class Class1
    {
        private void btn_click(object sender, EventArgs e)
        {
            ServerRequest sr = new ServerRequest();
            var callback = new ServerRequest.CallBackFunction(CallbackFunc);
            sr.DoRequest("myrequest",callback);
        }

        void CallbackFunc(string something)
        {

        }


    }
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.