程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> 多語言模式並舉: .NET語言和模式的調查

多語言模式並舉: .NET語言和模式的調查

編輯:關於.NET

本文討論:

面向對象的編程

函數式編程

動態編程

.NET 語言的新模式

本文使用了以下技術:

C#、C++、F#、IronPython、IronRuby、Visual Basic

Windows 操作系統 對編程人員而言是再合適不過的平台了。針對 Windows® 的語言有數百種,它們有的直接 通過 Win32® API 或 CLR 來實現,但更多的還是通過您的編寫來構建。

CLR 的目標之一就是要在一個兼容的生態系統中讓百花齊放,將語言和 API 無縫集成在同一運行時中 。到目前為止它已取得了巨大的成功——新的語言層出不窮。像 Ruby (IronRuby)、Python (IronPython) 和 PHP (Phalanger) 等 Microsoft 實現屬於動態語言范疇,它們現在是 Microsoft® .NET Framework 語言中的一流成員。最近還引入了被稱為 F# 的函數化語言。盡管您很可能曾經聽到過 有關這些新語言和語言模式的討論,但可能還是想知道其具體含義。

介紹這些語言模式並講述其 中一些重要實現的內容不但能夠解答您的疑問,而且還有助於說明其中的一些新語言和舊模式將會如何影 響 C# 和 Visual Basic® 語言未來版本的設計和實現。

要了解新設計所表現出來的變化,您 需要了解傳統語言(如 C# 和 Visual Basic)與新語言(如 F#、IronPython 和 IronRuby)之間的差異 。此方面主要涉及三大主題:面向對象的編程(C# 和 Visual Basic 這二者都利用的模型)、函數式編 程 (F#) 以及動態編程(IronPython 和 IronRuby)。讓我們看一看這些模式並探究一下他們的區別特征 。

面向對象

面向對象 (OO) 是您可能最為熟悉的一種模式。通過它您可以描述對象與綁定 它們之間交互的約定所構成的環境。OO 利用類型約定、多態性以及精細的可見性等多種功能來提供出色 的重用和封裝特性。

通常,面向對象的語言采用靜態類型系統,因此它們被稱為靜態類型語言。 這意味著程序創建和使用的所有類型都在編譯時進行檢查;這可防止您對 Duck 類型的對象調用方法 Moo (在此方法不存在的情況下)。在代碼運行之前,編譯器可檢測各種類型之間被破壞和誤用的約定,從理 論上講,這樣做可減少運行時錯誤。

但是 OO 也存在一些缺陷。類型安全性可能會使編程人員過 分依賴編譯器來捕獲錯誤,而不是親自創建必要的測試基礎結構。同時,OO 還會促使編程人員預先定義 自己的約定,而這往往是與快速原型編程和多用戶編程環境背道而馳的。在大型軟件項目中,組件之間的 約定(通常由不同的團隊所擁有)往往在整個開發周期中不斷演變,這就要求約定的使用者不斷更新其代 碼。由於上述這些問題,OO 語言可能顯得有些復雜和冗長。

函數式編程

函數式編程將程 序計算視為數學函數的計算。將兩個數字相加即為一個函數。假定有兩個輸入值,比方說是 5 和 10,則 輸出值便為 15。為解決某個問題,函數式編程人員會將該問題細分為多個可使用函數表示的較小的塊, 然後再將這些函數進行組合以生成預期的輸出。

函數式編程通常會避開狀態(類似於變量和對象 等內容)和狀態變異。這實際上是與 OO 相左的,後者的主要目的恰恰是為了創建和操作狀態(對象)。 由於避開了狀態,函數式程序往往更加准確、精密而且可驗證。這是由於它很少會產生不可預知的副作用 ——當程序(如某個變量)的內部狀態在各操作之間發生變化時可能會產生一些副作用,這些 副作用會導致在一個或多個操作中產生非預期的結果。面向對象的語言和動態語言依賴編程人員來封裝和 保護狀態,以減少不可預知的副作用,因為這些副作用會不可避免地導致更多錯誤的發生。

函數 式語言可以是很純粹的,也就是說沒有任何副作用或狀態。但是,大多數流行的函數式語言都具有狀態操 作功能,這有利於促進與外部 API、操作系統以及其他語言的互操作性。針對某些程序必須使用一定量的 狀態信息來表示問題這一事實,它們也有相應的考慮。

有一些很有用的功能,它們對函數式語言是通用的。就我個人而言,我比較喜歡高階函數,此函數可 以將另一個函數作為參數,並且返回結果可以是函數,這為代碼重用提供了強大的支持。雖然大多數語言 已嵌入了此機制,但函數式語言更傾向於將其提升為首要的功能。

下面將以一個典型的 Map API 為例來詳細介紹高階函數的功能,此示例對數組或數據列表中的每個元素都執行(或映射)一個函數。首 先,我們使用 JavaScript(一種常用的 Web 腳本編寫語言)來編寫此函數。給定此數組

var 

data = [1, 2, 3, 4, 5];

現在編寫將對數組中的每個元素執行代碼的函數,如下所示:

function map (func, array)
{
  var returnData = new Array(array.length);
  for (i = 0; i< array.length; i++)
  {
    returnData[i] = func(array[i]);
  }
    
  return returnData;    
}

下面的函數將按 1 遞增某個數值:

function increment(element)
{
  return element++;
}

現在讓我們開始使用它:

print (map (incremenent, data));
output: [2,3,4,5,6]

此處的 Map API 示例雖然非常簡單,但卻演示了高階函數的功能。Map 有一個函數和一個數組,它對每個數組元素都執行該函數,並在一個新數組中返回結果。

假定沒 有變異的狀態(為返回的結果創建一個新數組),並且沒有函數結果依賴於先前的結果,則現在即可開始 考慮將這一映射示例擴展到多個處理內核(通過將數組分成兩部分並將得到的兩個數組連接起來)乃至多 個計算機(跨 n 個計算機拆分序列化數據、將代碼函數傳遞到計算機、在一個單獨主機中執行並連接序 列化結果),而不必擔心諸如狀態管理等並發操作問題。如此強大的功能用在這裡真的是大材小用了!

編程語言 F# 最初是由 Microsoft Research 的 Don Syme 所開發,是 Microsoft 對有關 .NET Framework 函數化編程需求的回應。在發布時,它將是在 Visual Studio® 中受到全面支持的語言。 F# 和 Visual Studio 集成包均可從 go.microsoft.com/fwlink/?LinkId=112376 下載。另外,由 Robert Pickering 編寫的 Foundations of F# 對該語言做了精彩的介紹。

言歸正傳,下面我們 將使用 F# 來探究函數化語言環境的內幕。我們仍以 Map 為例,但這次是在 F# 中:

// 

increment function
let increment x = x + 1
// data
let data = [1 .. 5]
// map (func, myList)
let map func myList =
 { for x in myList -> func x }
print_any (map increment data)

的確,它非常簡潔。第一行定義一個簡單的遞增函數,它有 一個參數 x,此函數將計算 x + 1。然後,將數據定義為一個不可變異的列表,其中包含整數 1 到 5。 此映射函數以函數和列表作為參數,使用傳統編程中的噴淋方法來遍歷列表並執行 func 函數參數,然後 將列表中的當前元素傳遞給它。接下來,print_any 函數使用增量函數和數據列表作為參數來執行映射函 數,隨後將結果打印到屏幕。

類型在哪裡?在本例中並不存在。實質上,變量(數據)實際被類 型化為 System.Int32 的列表,但並不需要將此告知編譯器,因為它使用類型推斷功能即可推斷出這一情 況。編譯器做的工作越多,您的工作就會越少。這聽起來非常不錯。使用列表推導功能,您在一行內就可 以輕松地重寫先前的部分代碼:

print_any { for x in 1..5 -> x + 1 }

另一個 很酷的 F# 功能是模式匹配:

let booleanToString x =
  match x with false -> "False" | _ -> "True"

此函數具有 一個 Boolean 類型,此類型可與 false 或任何其他值匹配,並返回相應的字符串。如果向 booleanToString 函數傳遞一個字符串,會出現什麼結果?同樣,編譯器承擔了繁重的工作,將 x 參數 的類型定義為類型 bool。它通過 x 在此函數中的用法推斷出這一點(在這種情況下,它僅與 bool 類型 相匹配)。

模式匹配還可以用於構建強大的函數調度機制,以便在 OO 及其他環境中輕松地重現 虛擬方法調度。當您需要根據接收方(將在此對象中調用虛擬方法)和方法參數的變化來改變行為時,虛 擬方法才真正開始起作用。訪問者模式即是為了幫助解決這種情況而設計的,但是在 F# 中基本不需要( 已包含在模式匹配中)。

支持用戶定義的類型,通常由記錄(類似於 OO 環境中的類)或聚合(通常是一種有序序列類型)提 供。以下是用戶定義的隊員和球隊記錄:

type player =
 { firstName : string;
  lastName : string;
 }
type soccerTeam =
 { name : string;
  members : player list;
  location : string;
 }

延遲計算是另一種常見的函數式語言功能,其功能源自這樣一種理論,即函數化編程中沒有 明顯的副作用。延遲計算依賴於編譯器和編程人員選擇表達式計算順序的能力,它可以使計算延遲到所需 的時間點。編譯器和編程人員都可以使用延遲計算技術作為精確的性能優化手段,因為它可以避免一些不 必要的計算。在處理無限(或極大)數據集的計算時,它也是一種有用的技術。實際上,Microsoft Research 的 Applied Games 研究組曾在 F# 中使用此技術解析過數 TB 字節的 Xbox LIVE® 日志數 據。

以下是 F# 中的延遲計算:

  let lazyTwoTimesTwo = lazy (2 * 2)
  let actualValue = Lazy.force lazyTwoTimesTwo

此代碼執行時,lazyTwoTimesTwo 只是 在運行時充當指向執行 2 * 2 的函數的輕型指針。僅當實際強制執行此函數時,才能獲得結果。

雖然函數化編程模型可能不太容易理解(可能需要 30-40 小時的准備時間),但一旦掌握它,您的編程 能力就會有質的飛躍。您只需使用很少的代碼就可以解決問題並減少錯誤。此模式通過最大程度減少意外 的副作用來保護代碼的安全,並通過執行積極的優化措施使其保持快速運行狀態。此外,簡單性往往代表 出色的擴展性——您只需看一下 Map 代碼,想想該代碼如何能夠輕松分布到成千上萬台計算 機中,就可以了解其中的緣由了。

至此,您已經看到了函數化編程的一些非常出色的功能,例如 類型推斷、高階函數、模式匹配和用戶定義類型等。現在讓我們了解一下動態語言。

動態語言

動態編程早在 20 世紀 90 年代中期就開始流行了,當時正是基於 Web 的應用程序大行其道的時 候。在將服務器上的交互式動態元素添加到它們所驅動的網站上時,Perl 和 PHP 是最常用的兩種動態語 言。從那以後,動態語言開始獲得越來越多的驅動力,為新一代軟件開發方法(如敏捷開發)指明了技術 出路。

在編譯和執行程序代碼方面,動態編程語言與靜態語言(C# 和 Visual Basic .NET 均為 面向對象的靜態語言)有所不同。使用動態語言時,代碼編譯通常會被延遲到運行時,即當實際開始運行 程序的時候。在其他情況下,只是簡單地對代碼進行解釋。通過編譯過程中的這些延遲功能,程序代碼可 以包括並執行諸如動態擴展對象等行為,並允許編程人員根據需要來處理類型系統。

實際上,正 是將進程延遲到最後一刻的實時 (JIT) 編譯和執行技術為動態語言賦予了強大而又豐富的功能集。因此 ,動態語言通常被稱為後期綁定,因為所有操作綁定(如調用方法或獲取屬性)都是在運行時而非編譯時 完成的。為了說明動態語言的一些功能,下面我們將詳細介紹一下 IronPython 和 IronRuby。

IronPython 是 .NET Framework 中 Python 編程語言的 Microsoft 實現。它是 Jim Hugunin 智 慧的結晶,其原型最早是誕生在 Jim Hugunin 的車庫中。六個月後,Jim Hugunin 加入了 Microsoft 並 構建了 IronPython 編譯器。您可以從 go.microsoft.com/fwlink/?LinkId=112377 下載 IronPython 的 完整源代碼和安裝程序。

IronRuby 是為 Ruby 編程語言的 Microsoft 實現所賦予的名稱。John Lam 是一名活躍的 Ruby 黑客,他編寫了名為 RubyCLR 的 Ruby-to-CLR 橋梁。後來他加入了 Microsoft 的 IronRuby 團隊。您可以從 ironruby.net 下載完整的 IronRuby 源代碼。

接下來,我們將開 始使用 IronPython,介紹一項名為 Read Eval Print Loop (REPL) 的出色功能。REPL 循環被設計用於 逐行輸入代碼並執行。它實際展示的是動態語言(如 Python)的後期綁定性質。圖 1 顯示了 IronPython 的命令行 REPL 循環。

圖 1 IronPython REPL 循環

REPL 循環接受 Python 代碼作為輸入,然後它將立即執行代碼。 在本例中,我想讓它將 "Hello, World!" 打印到屏幕上。只要編程人員敲擊一下 Enter 鍵, IronPython 編譯器就會將該語句編譯為中間語言 (IL) 並執行(全部都在運行時中)。

REPL 循環還遵循該語言的全部作用域規則,在本例中,我將表達式 1 + 2 賦給了變量 "a",在下一行中我將可以引用此變量。REPL 輸入內容的編譯是在進程內進行的。無需生成 .dll 或 exe 文件;IronPython 編譯器僅使用 CLR 的內存代碼生成功能,即輕量級代碼生成 (LCG)。

動態語言的類型系統非常靈活,而且要求寬松。通常它可以支持面向對象的概念(如類和接口),不 過需要注意:在靜態語言中存在的嚴格的約定強制執行情況在這裡一般不會出現。對於這一相對較為寬松 的類型系統,一個典型示例就是鴨子的類型化概念,這是一種受到廣泛支持的動態語言類型系統功能。在 鴨子類型化中,如果某個類型看上去像鴨子並且叫起來也像鴨子,則編譯器就會假定它是鴨子。圖 2 使 用 Ruby 顯示了運行中的這一概念,如果願意,您也可以在 IronRuby 中運行此代碼。

Figure 2 Ruby 中的鴨子類型化

class Duck
def Quack()
puts "Quack!"
end
end
class Cow
def Quack()
puts "Cow's dont quack, they Mooo!"
end
end
def QuackQuack(duck)
duck.Quack()
end
animal = Duck.new()
QuackQuack(animal)
animal = Cow.new()
QuackQuack(animal)

圖 2 顯示了兩個類定義(Duck 和 Cow)、一個名為 QuackQuack 的方法以及用來實例化這些對象的 代碼,然後又將對象傳遞給 QuackQuack 方法。此代碼在加載並運行後會輸出以下內容:

Quack!
Cow's don't quack, they Mooo!

QuackQuack 方法通過方法參數調用 Quack 方法,它並不關心該參數的類型,只關心該參數是否有方 法 Quack。Quack 方法的查找和調用是在此參數的運行時而非編譯時進行的,這將允許編程語言先確保該 參數看上去形似鴨子,然後再考慮其叫聲。

在靜態類型化環境中,接口就類似於上面所說的鴨子類型化。如果某個類型要在靜態環境中實現某個 接口,則靜態類型系統會強制其遵循全部完整的接口結構,以使對任何實現類型的接口方法調用都能夠得 到保證。鴨子類型化僅關注類型的結構部分,即所處理的方法名稱。它通過後期綁定來實現該目的——編 譯器只生成代碼,對對象執行方法查找(通常使用基於字符串的方法名稱),然後再調用該方法(如果查 找成功)。

在 IronPython 和 IronRuby 等動態語言中,語言功能並非是唯一的亮點。動態語言甚至還允許您托 管 API,這意味著您可以在自己的應用程序中托管語言、編譯器甚至 REPL 交互式功能。假設您正在構建 一個龐大而復雜的應用程序(例如照片處理工具),而且您希望為用戶提供一個自動化或腳本處理工具。 您可以托管 IronPython 或 IronRuby 並允許用戶創建 Python 或 Ruby 腳本,使其可以通過編程方式來 操作您的應用程序。為此您只需將應用程序的內部對象和 API 提供給托管 API 的語言、創建一個文本窗 口來托管 REPL 循環、然後在應用程序中啟用腳本編寫功能即可。

使用諸如命令行驅動 REPL 循環等功能可以在生產力方面帶來非常不錯的連帶效應:您可以輕松地構 造工作原型而不必執行保存-編譯-運行這一周期。我們提倡動態修改和擴展類型,這可以使您快速獲得解 決方案(從構想到代碼),而無需擔心接口或類定義約定的形式。取得進展後,您即可從動態語言原型轉 到更嚴格、更安全的靜態語言環境(如 C#)中。

實際上,靈活的類型系統還擅長處理非結構化的數據(如 Web 上的 HTML),對於可能會隨著時間的 推移而更改版本的嚴格接口而言,可以很容易地將其用作防更改粘合劑。在基於 Web 的計算等新興應用 程序模式中,動態語言提供了一種用於處理不確定情形的強大解決方案。

托管 API 會為您的應用程序提供一個最佳的擴展點;您可以提供與 Microsoft Excel 和 VBScript 宏類似的應用程序體驗。

安全實用

安全性和實用性也是在語言選擇中需要考慮的重要事項。語言的實用性可通過其易用性、高效性等因 素來衡量。語言安全性的衡量標准包括其類型安全性(是否允許無效轉換)、編程屏障(是否會跨越數組 邊界並影響堆棧中的其他內存內容)、安全功能等等。有時您可以犧牲實用性來換取安全性,反之亦然。

有趣的是,您會發現 C#、C++、Visual Basic .NET、Python 及類似的語言實用性很強,但缺少安全 分類。雖然托管代碼語言(如 C#)要比傳統的本機代碼安全一些,但您仍可能會遇到麻煩。由於這些語 言關注的是狀態操作,因此它們通常都有一些未知的副作用——在並發環境下工作時,這將會是一個問題 。

在單核計算機中可以正常運行的一個 C#/Visual Basic .NET 多線程程序,在多核計算機中運行時可 能會崩潰,這是由於爭用條件引發了一個編程人員所不知道的副作用。另外,盡管這些語言具有良好的一 般等級的類型安全性,但是它們仍然無法防止編程人員在沒有察覺的情況下將某個對象轉換為 void*。

Haskell(學術界使用的一種純函數式語言)屬於雖然安全但實用性稍差的一類。由於 Haskell 沒有 副作用(代碼塊是函數,變量永遠不會變化),而且它會強制編程人員預先定義其類型和意圖,因此它被 視為一種安全語言。遺憾的是,Haskell 極難理解,甚至對技術精湛的編程人員也是如此,因此通常很難 讀懂他人所編寫的 Haskell 代碼。

在我看來,考慮到與 .NET Framework 的集成、可選的過程語法、處理面向對象環境下的 Objects 的 能力等特點,因此 F# 要比 Haskell 更為實用。很顯然,下一代語言會很好地借鑒我所介紹的這些語言 的長處。如果有一種語言能夠將呆板、強制性的靜態類型系統動態地變為動態、靈活的類型系統,不但具 有函數化編程功能而且可以避免並發問題,那有誰會不喜歡這種語言呢?

令人欣慰的是,由於通用類型系統 (CTS) 的出現,現在可以很容易地從 C# 轉換到 F# 和 IronPython,然後再重新轉換回來。而且 C# 和 Visual Basic .NET 的設計人員借鑒了動態模式和函數 化模式的長處,將其直接集成到了這些語言中作為優先功能。接下來讓我們了解一下其中的幾個功能,看 一看它們是如何與您已經了解的各種語言及其模式相關聯的。

LINQ

LINQ 是 .NET Framework 中的一項新功能,可直接用作 .NET 中任何語言的 API,也可以通過一組 LINQ 語言擴展來實際作為一種語言功能。通過提供一組與 T-SQL 語言類似的查詢運算符,LINQ 可以使 用一種與存儲無關的方式來查詢數據。.NET Framework 3.5 中的 Visual C# 2008 和 Visual Basic 2008 均支持 LINQ 作為一流成員。

使用 Visual C# 2008 執行的典型 LINQ 查詢如下所示:

List<Customer> customers = new List<Customer>();
// ... add some customers
var q = from c in customers
where c.Country == "Australia"
select c;

此代碼會遍歷客戶列表,查找包含 Country 屬性且屬性值為 "Australia" 的 Customer 對象,然後將其添加到新列表中。首先您會注意到關鍵字 "var",它是 Visual C# 2008 中新 增的一個關鍵字,用來告訴編譯器執行類型推斷。然後您會看到操作中的 C# LINQ 擴展,其中包含 from 、where 和 select 關鍵字。這些構成了一個完整的客戶列表(列表推導),正如您在 F# 語言中看到的 ,這是動態語言中的一個常見功能。

由於您是在此 LINQ 查詢執行時新建列表,因此實際上沒有任何副作用,原始客戶列表不會發生改變 。副作用對每個並發程序而言都是一件很麻煩的事,但這種編程風格會在副作用中為您帶來安全性,同時 維護代碼的可讀性和整體實用性。假定沒有任何副作用,則您可根據需要對查詢范圍進行擴展。

實際上,這正是 Parallel LINQ (PLINQ) 的目的所在,它是對 LINQ 的擴展,作為社區技術預覽通過 Parallel FX 庫 (go.microsoft.com/fwlink/?LinkId=112368) 提供給用戶——跨多個 CPU 核心並行執 行 LINQ 查詢,這樣不但使查詢速度幾乎呈線性增加,而且不會增加編程成本!這與函數式編程部分列舉 的 Map API 示例非常相似。總之,LINQ 在 C# 和 Visual Basic 中的集成不但增加了一個函數類型,還 引入了一些活力,它使這些語言更具表現力,而且更簡練。

Visual Basic 9.0 中的內嵌 XML

有人說內嵌 XML 是 Visual Basic 中添加的最佳功能,我完全同意。雖然它不像是源自函數式或動態 模式的內容,但它的實現是直接在動態語言環境中完成的。圖 3 顯示了在 Visual Basic 中內嵌的 XML 。

Figure 3 操作中的內嵌 XML

Dim rss = From cust In customers _
Where cust.Country = "USA" _
Select <item>
<title><%= cust.Name %></title>
<link><%= cust.WebSite %></link>
<pubDate><%= cust.BirthDate %></pubDate>
</item>
Dim rssFeed = <?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"><channel></channel></rss>
rssFeed...<chan nel>(0).ReplaceAll(rss)
rssFeed.Save("customers.xml")

此代碼使用 Visual Basic LINQ to XML 實現來查詢客戶列表中那些居住在美國的客戶,並返回 XML 元素的列表作為 RSS 源的基礎。然後,此代碼定義 RSS 源架構並使用 Visual Basic 中非常奇妙的 "..." 運算符來遍歷 XML 文檔以查找 "<channel>" 元素。接下來,代碼對 該 <channel> 元素調用 ReplaceAll,以包括在先前創建的所有 XML 元素。大功告成。

在這裡需要注意的是 ... 運算符以及內嵌 XML 元素的使用。請注意,Visual Basic 並不知道 XML <channel> 元素(實際上,您可以將其改為 <foo>,它也會正常編譯),因此說,如果 Visual Basic 不知道這一點,可能就無法靜態檢查該調用點是否正確。相反,在這裡編譯代碼將會在運 行時執行動態檢查(類似於您在動態模式下見到的檢查)。它利用的是後期綁定中的動態語言概念。

對於早餐准備享用 IL 的用戶,讓我們打開程序集,看一看 "...<channel>" 語句 的代碼:

ldloc.1
ldstr "channel"
ldstr ""
call class [System.Xml.Linq]System.Xml.Linq.XName
[System.Xml.Linq] System.Xml.Linq.XName::Get(string,
string)
callvirt instance class Generic.IEnumerable'1<XElement>
XContainer::Descendants(System.Xml.Linq.XName)

Ldloc.1 加載 rssFeed 變量、加載 channel 字符串,然後調用 XName.Get 方法,此方法返回 Xname 。此 XName 結果被傳遞給 Descendants 方法,然後此方法返回與 <channel> 名稱匹配的所有 XML 文檔後代。此機制是典型的後期綁定動態調度,它直接借用了動態語言的內容。

別急,還有一些內容需要討論。如果將 RSS 架構定義置入 Visual Studio 中並添加對此架構的 "Imports" 引用,則 Visual Basic .NET 編譯器將提取此架構並加以分析,然後對符合此架 構的所有 XML 啟用完整的 IntelliSense。因此,如果您進入 RSS XML 架構中, "...<channel>" 語句會立即顯示一個 IntelliSense 窗口,其中包含根據架構定義提 供的各種可能的後代選項。太棒了!

更多資源

有關 C# 和 Visual Basic 等語言如何與其他模式和語言的最佳元素相結合的內容,我僅提及了少數 幾個示例。現在,語言設計團隊正在向其語言中增加新的類型,以應對未來編程的挑戰。

雖然我們已經探討了幾個高級別的編程模式類別,但這些只是其中的一部分。聲明性編程(描述某種 事物的方法)使用 XML 作為描述符,對通過框架(如 Windows Presentation Foundation 和 Windows Workflow Foundation)進行的開發有著巨大的影響。它們還非常擅長描述和操作數據。隨著組織多年來 所創建的數據資產的不斷增長,如果今後想嘗試通過編程方式來開發這些資產,我想聲明性語言會成為其 中的驅動力。還有一種邏輯編程(利用計算機編程邏輯),雖然我沒有提及這種編程方法,但它與 Prolog 等語言一起被廣泛地應用在人工智能和數據挖掘領域。

隨著不斷向所有這些語言和模式中添加各種新功能,您也必將從中獲益。通過這種取長補短,您所喜 愛的語言會變得更加完善,而您也可以獲得更大的靈活性和更高的生產率。如果您想使用其他語言中的一 些比較出色的功能,這也好辦;您所喜愛的運行時和框架已經開始支持這種互操作情形。作為一名 .NET 編程人員真是太棒了。

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