Geri arama işlevini başka bir sınıfa iletme


91

Temelde bir yöntemi daha sonra çağrılmak üzere başka bir sınıfa geçirmeye çalışıyorum, ancak bunu C # ile tam olarak anlayamıyorum (hala Objective-C'ye alışkınım).

public class Class1{

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

    public void myCallback(string str)
    {
    }
}

Daha sonra ServerRequest sınıfımın temelde geri arama işlevini çalıştırmasını istiyorum, bu mümkün değil mi? (Temel olarak yazılımıma bir oturum açma yanıtı için bir sunucuya evimi arıyorum)

Temsilcilerle bunu yapmanın bir yolunu bulamadım, sürekli hata alıyorum. İşte diğer sınıf:

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

Bu # içinde mümkün mü? Objective-C'de bu basit olurdu ve ben sadece şöyle bir şey yapardım

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

Yanıtlar:


140

Olarak iletebilirsiniz Action<string>- bu, stringhiçbir şey döndürmeyen (void) tek bir tür parametresine sahip bir yöntem olduğu anlamına gelir :

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

Ve DoRequest'i nasıl çağırırsınız? Bir dizge veya yöntem iletiyor musunuz?
Kokodoko

1
Eylem hakkında diğer merak edilenler için. işte hızlı bir ipucu. birden çok tür parametresi olabilir ancak dönüşü yoktur (yalnızca c # üyelerini geçirmek için Action <type1, .., typeN> türler üzerinde değiştiriciye izin vermez Fonksiyonu geçirmek için, Func <typeList> 'i tekrar kullanın. liste aslında işlev dönüş türüdür Action ve Func basit delegeleri kullanmanın hızlı yoludur
gg89

Günümü basit ve temiz hale getirin!
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

Temsilciler güçlü bir şekilde yazıldığından, önce temsilcinin türünü bildirmelisiniz:

public void MyCallbackDelegate( string str );

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

Kodunuzun birçok yerinde aynı yöntem imzasını kullanıyorsanız, bu harika bir çözümdür.
mtmurdock

4
Çağırmadan önce geri arama yönteminin boş olup olmadığını kontrol etmek iyi bir uygulamadır.
Maciej

4

Delegatesadece temel sınıf olduğundan, onu böyle kullanamazsınız. Yine de bunun gibi bir şey yapabilirsiniz:

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

2
Func<string>bir dize döndüren bir yöntem olacaktırAction<string>
buna

@BrokenGlass haklısın benim hatam - güncellenmiş (cevabını + 1d ettim)
Robbie

4

Kodunuzu şu şekilde değiştirebilirsiniz:

public delegate void CallbackHandler(string str);

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

2

İhtiyacınız olan şey bir temsilci ve bir geri arama. İşte bu tekniği C # 'da nasıl kullanacağınızı gösterecek güzel bir MSDN makalesi.


2

Yalnızca geri arama işlevleri için en iyi olan temsilciyi kullanabilirsiniz:

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

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

ve bunu aşağıdaki gibi tüketin:

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

        }


    }
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.