Передача функції зворотного виклику іншому класу


91

В основному я намагаюся передати метод іншому класу, який буде викликаний пізніше, але не можу зрозуміти це в C # (я все ще занадто звик до Objective-C).

public class Class1{

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

    public void myCallback(string str)
    {
    }
}

Потім пізніше я хочу, щоб мій клас ServerRequest в основному запускав функцію зворотного виклику, чи це не можливо? (В основному я телефоную додому на сервер для відповіді на вхід до мого програмного забезпечення)

Я не зміг знайти спосіб зробити це з делегатами, постійно отримувати помилки. Ось інший клас:

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

Чи можливо це в #? У Objective-C це було б просто, і я б просто зробив щось подібне

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

Відповіді:


140

Ви можете передати його як Action<string>- що означає, що це метод з одним параметром типу, stringякий нічого не повертає (void):

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

А як ви телефонуєте DoRequest? Ви передаєте рядок або метод?
Кокодоко 12.03.15

1
для інших, хто цікавиться дією. ось короткий підказка. він може мати кілька типів парм, але не повертається (для передачі лише членів c # Дія <type1, .., typeN> не дозволяє модифікатор для типів. Щоб передати функцію, знову використовуйте Func <typeList> без модифікатора для будь-якого типу останнього типу в list - це тип повернення функції, фактично Action і Func - це швидкий спосіб використання простих делегатів
gg89

Зробіть мій день простим і чистим!
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

Спочатку потрібно оголосити тип делегата, оскільки делегати сильно вводяться:

public void MyCallbackDelegate( string str );

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

Це чудове рішення, якщо ви використовуєте той самий підпис методу у багатьох місцях у своєму коді.
mtmurdock

4
Радимо завжди перевіряти, чи не є метод зворотного виклику нульовим, перш ніж його викликати.
Мацей

4

Delegateє лише базовим класом, тому ви не можете використовувати його таким чином. Однак ви можете зробити щось подібне:

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

2
Func<string>буде методом, який повертає рядок - вам потрібенAction<string>
BrokenGlass

@BrokenGlass ти маєш рацію, погано - оновлено (я поставив +1 до вашої відповіді)
Роббі

3

Ви можете змінити свій код таким чином:

public delegate void CallbackHandler(string str);

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

2

Вам потрібен делегат та зворотний дзвінок. Ось приємна стаття MSDN, яка покаже вам, як використовувати цю техніку в C #.


2

Ви можете використовувати лише делегат, який найкраще підходить для функцій зворотного виклику:

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

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

і споживайте це, як показано нижче:

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)
        {

        }


    }
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.