程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> 關於C# >> C#動靜結合編程之一: 接口和委托的約束強度

C#動靜結合編程之一: 接口和委托的約束強度

編輯:關於C#

程序世界有兩種神秘的元素,它們無處不在,卻常常未被察覺。它們一動一靜,卻又和諧相處。我給 這對兄弟取上不太恰當的名字,一個叫“協議”,一個叫“約束”。我們常常看到的動態語言、靜態語言 背後,本質上就是“協議”與“約束”兩種元素的作用。靜態語言和動態語言本身沒有一個明確的界限, 它們各有優勢,又各有不足。

C#是一門優美的語言,它融合了靜態和動態的優勢,如果運用得當,必能動靜結合,呈現出一種和諧 之美。特別是.NET平台和語言的快速發展,更展現了動靜結合編程的活力。本篇是.NET動靜結合編程的第 一篇,希望這個系列能和大家一起探討如何在.NET平台上最大限度的發揮動靜結合的潛能。本人還只 是.NET的初學者,對計算機理論的理解還很膚淺,文中錯誤歡迎批評指正,不足之處歡迎補充,謝謝!

被忽略的協議

談到“協議”,最先浮現在我們腦海中的可能是TCP/IP協議棧,但其實我們隨處都在和協議打交道。 下面的例子,你看出協議來了嗎?

B(){
    ArrayList lst = A();
    foreach (string item in lst){
        Console.WriteLine(item.Length);
    }
}

方法B假定方法A遵守:返回的ArrayList內部都是string類型的元素。這就是它們之間的協議,這個協 議不受編譯器靜態檢查的約束。所以,協議意味著運行時的不確定性,方法A完全可能在返回結果中裝入 非string類型的元素,而這將導致B在運行時產生異常。

.NET2.0通過泛型集合增加了靜態類型約束:

B(){
    List<string> lst = A();
    foreach (string item in lst){
        Console.WriteLine(item);
    }
}

這樣,B再也不用擔心lst內部存在非string類型的元素了,一切得益於泛型為A加上的靜態類型約束。

約束有強弱

約束有強弱之分。越強的約束越安全,靜態性越強,受編譯器的支持越大;反之,越弱的約束,動態 性越強,運行時靈活性越大。

常常看到關於單方法接口和委托異同的討論,不少朋友認為它們完全等價。其實,它們有明顯不同的 約束強度。接口是靜態類型約束,而委托只是靜態簽名約束,二者的強度完全不同。換句話說,委托具有 更多的協議性,只要符合簽名,都可以被委托調用,而能被接口調用的對象必須實現該接口。

來看一個例子:需要編寫一個類A,其內部需要日志功能;A采用IoC方式,不依賴於具體的Logger類, 由使用者根據需要注入具體的實現;同時,A的使用者B,希望采用第三方的Logger類。

a. 基於接口的IoC

interface ILogger { void Write(string msg); }

class A{
    ILogger Logger { get; set; }
    void F() {}
}

class B{
    G(){
        A a = new A();
        a.Logger = new LogAdapter(); //注入依賴
        a.F();
    }
}

//對第3方Logger進行包裝
class LogAdapter : ILogger{
    Write(string msg){//這裡調用第3方的Logger類}
}

b. 基於委托的IoC

class A{
    Action<string> Logging { get; set; }
    void F() {}
}

class B{
    G(){
        A a = new A();
        a.Logging = delegate(string msg){ //調用第3方Logger類 };
        a.F();
    }
}

比較上面兩個例子,我們就會發現委托比接口的約束要弱得多,使用起來靈活得多。基於接口的實現 不得不增加一個Adapter去機械地適應接口的類型約束,而基於委托的實現只需要保證方法簽名約束即可 。

後續

後續章節打算陸續介紹DuckTyping、泛型委托妙用、表達式樹和lambda、.NET4.0動態編程等相關內容 ,敬請關注,多謝批評!

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved