別のクラスにコールバック関数を渡す


90

基本的に、メソッドを別のクラスに渡して後で呼び出そうとしていますが、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];

回答:


139

あなたはそれを次のように渡すことができますAction<string>-つまり、string何も返さないタイプの単一のパラメーターを持つメソッドであることを意味します(void):

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

そして、どのようにDoRequestを呼び出しますか?文字列またはメソッドを渡しますか?
Kokodoko 2015年

1
アクションに関する他の好奇心のために。ここに簡単なヒントがあります。複数の型パラメーターを持つことはできますが、戻り値はありません(c#メンバーのみを渡す場合、Action <type1、..、typeN>は型の修飾子を許可しません。関数を渡すには、Func <typeList>を再度使用します。 listは実際には関数の戻り値の型
です。Action

シンプルでクリーンな一日を!
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 2012年

4
コールバックメソッドを呼び出す前に、コールバックメソッドがnullでないかどうかを常に確認することをお勧めします。
Maciej 2012年

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

必要なのはデリゲートとコールバックです。これは、このテクニックをC#で使用する方法を示すすばらしいMSDN記事です。


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

        }


    }
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.