從OC和C#中找樂趣:相同又不同的delegate

丶Pz發表於2016-04-07

  不想說話,本來第一段打了一大堆廢話,結果瀏覽器崩潰了。。。直接進入正題吧。看Demo:

  C#裡面也有delegate,我今天的目的就是模仿著OC裡面的寫法來寫一個網路請求模擬類。先建一個“Protocol”,當然在C#裡面就是一個普通的兩個delegate方法。

  

namespace DelegateTest.PZNetRequestEvent
{

    /// <summary>
    /// 請求成功代理約束:引數為 object型別
    /// </summary>
    /// <param name="result"></param>
    public delegate void RequestSuccessHandler(object result);
    /// <summary>
    /// 請求失敗代理約束:引數也為object型別
    /// </summary>
    /// <param name="error"></param>
    public delegate void RequestFailerHanlder(object error);

}

  下面定義一個Request類,這個類就一個作用,發起網路請求,它裡面有兩個 event ,沒錯,一個就是 RequestSuccessHandler,另外一個RequestFailerHanlder

        /// <summary>
        /// 定義成功代理
        /// </summary>
        event RequestSuccessHandler RequestSuccess;
        /// <summary>
        /// 定義失敗代理
        /// </summary>
        event RequestFailerHanlder RequestFailer;

  然後我們也定義一個init方法,引數就是具體的代理了。代理(介面)定義了符合 RequestSuccessHandler 和RequestFailerHandler的兩個方法

 public interface PZNetRequestDelegate
    {
        void PZNetRequest_RequestFailer(object error);
        void PZNetRequest_RequestSuccess(object result);
    }

 

  init方法如下:

  public void init(PZNetRequestDelegate target)
  {
       //註冊代理事件
        RequestSuccess += target.PZNetRequest_RequestSuccess;
        RequestFailer += target.PZNetRequest_RequestFailer;
   }

  最後,發起請求的方法

/// <summary>
        /// 開始請求
        /// </summary>
        /// <param name="url"></param>
        /// <param name="parameters"></param>
        public void StartRequest(string url, Dictionary<string, object> parameters)
        {
            Console.WriteLine("發起請求。。。");
            Thread.Sleep(1000);//模擬網路請求一秒

            if (url == "success")
            {
                RequestSuccess("success"); //因為註冊了代理的實際方法,所以,此方法會呼叫代理的方法
            }
            else
            {
                RequestFailer("error");//因為註冊了代理的實際方法,所以,此方法會呼叫代理的方法
       }
     }

  在編寫一個類實現介面:

 public class PzDelegateRequestDemo : PZNetRequestDelegate
    {
        public void PZNetRequest_RequestFailer(object error)
        {
            Console.WriteLine("請求失敗:" + error.ToString());
        }

        public void PZNetRequest_RequestSuccess(object result)
        {
            Console.WriteLine("請求成功:" + result.ToString());
        }
    }

  到這裡呢,一個簡單的網路請求,然後用代理處理返回結果就實現了。雖然和OC 語法有不同的地方,但我感覺還是大同小異。不過還是感謝OC的語法讓我明白了C#的代理。說來真是慚愧。。。主打.NET開發的我,如今才稍微弄明白一點代理。下面我們測試一下程式碼

 

  static void Main(string[] args)
        {
            //new一個網路請求類
            PZNetRequest request = new PZNetRequest();
            //new 一個delegate
            PZNetRequestDelegate requestDelegate = new PzDelegateRequestDemo();
            //將delegate 傳入 request 初始化
            request.init(requestDelegate);
            //開始傳送請求,請求成功和失敗,將在delegate中處理
            request.StartRequest("success", null);
            request.StartRequest("failer", null);

            Console.Read();
        }

  好,執行,看一下結果吧,與預期的一致。

 

總結:C#裡面其實有好多功能我是不曾用也不會用的,原來學學其他語言將兩者相比有如此多的樂趣,下篇預告:OC的block  和 C# 的Func<>的相似之處

最後貼上部分OC 代理的程式碼:

1.定義protocol

@protocol PZBaseRequestDelegate <NSObject>

@optional
-(void)requestSuccessWithRequest:(__kindof PZBaseRequest *)request;
-(void)requestFailedWithRequest:(__kindof PZBaseRequest *)request;
-(void)requestFailedWithNetworkUnConnected;
@end

2.request中定義代理變數delegate

@interface PZBaseRequest : NSObject

@property(nonatomic,weak) id<PZBaseRequestDelegate> delegate;

3.request中呼叫代理方法如下。

 if (request.delegate && [request.delegate respondsToSelector:@selector(requestFailedWithNetworkUnConnected)]) {
      [request.delegate requestFailedWithNetworkUnConnected];
  }

4.實戰應用,將request的代理設為self(xxController),xxController要實現 Protocol

@interface PZHomeCostListController()<PZBaseRequestDelegate>

-(PZGetAccountListRequest *)request { if (_request == nil) { _request = [[PZGetAccountListRequest alloc] init]; _request.delegate = self; //必不可少 } return _request; }

5.實現代理方法即可,然後在代理方法中處理業務邏輯

#pragma  mark network delegate
//請求成功
-(void)requestSuccessWithRequest:(__kindof PZBaseRequest *)request
{
   
}
//  請求失敗
-(void)requestFailedWithRequest:(__kindof PZBaseRequest *)request{
  
}
//無網路
-(void)requestFailedWithNetworkUnConnected
{
   
}

 

Demo下載地址:https://github.com/fanpan26/DelegateTest

相關文章