把我的爱送给你――C#3.5(这题目似乎写错了)
本文發表于 中國IT實驗室周報。這是我初次寫給雜志社稿件,其中必有許多不足之處,還望大家見諒,雖然這篇文章質量可能不太高,但我希望能將個人的這些總結與大家分享。
?
從筆者接觸編程至今,經歷了數種編程語言,從Visual Basic6.0桌面程序開發到ASP(VBScript)的網站開發,從C#1.1到C#2.0,再至今日的令人加心動的C#3.5,筆者曾多次為Windows平臺下的編程感慨——越來越方便的操作,越來越強大的功能,越來越簡潔的代碼使得由代碼組成的編程世界中平添的許多色彩與歡樂。
以上可以算作對即將要介紹的C#3.5新特性的一個鋪墊。筆者對于C#的愛,勝過其他的任何語言,尤其對于剛剛召開不久的微軟2008新技術大會上發布的Visual Studio 2008筆者的愛意更甚。于是,筆者決定將自己對它的愛以文章的形式來表達。
讓我們去由此開始,向C#3.5示愛:
一、告訴C#3.5,我們對愛上它的曖昧-var關鍵字
曖昧?眾所周知,C#從出生以來都是很以一種強類型的語言示人的,并不像JavaScript和VB6.0那樣給人以“曖昧”的感覺啊?而在此處介紹的關鍵字var,是否讓您想起了JavaScript中的定義變量的關鍵字var?事實上,這兩個看似相同的關鍵字卻有本質上的區別。而這個var關鍵字并非在C#3.5中才出現的,它在C#3.0中便已經存在,筆者之所以在此介紹它,是因為欲介紹3.5,必須而且應該去介紹一下這個在C#3.0中便出現的特性——本地類型推斷(Local Type Reference),如若不然,筆者內心便無法安穩。
在C#2.0及其以前的版本中,如若定義一可以向其賦任何值的變量,那么我們需對其以object關鍵字進行定義,這種變量需要對值類型的進行裝箱操作而且在對該變量使用的時候還需要進行相應的拆箱操作,而這種裝箱拆箱所耗費的資源實在是筆者所不愿意看到的。
那么,我們既不愿意編寫無謂耗費資源的代碼,又想去實現object定義變量實現的功能,怎么辦?C#3.5為我們提供了一種變量定義方式:
(圖1,1.jpg)
看上面的變量定義,奇怪么?其實這就是C#3.5為我們提供的一種新功能——本地類型推斷,它可以保護類型安全,而且允許您編寫更為“自由”的代碼。也就是說,我們可以不去考慮變量的類型而直接以var關鍵字去修飾它,編譯器能夠從給變量賦值的表達式中智能推斷出變量的類型。它和COM模型中的Variant關鍵字定義出的變量完全不同,COM中的Variant關鍵字是后期綁定的一種方式,在編譯期沒有檢測,僅在代碼運行時才會出現它自身存在的問題,而且一不小心就會出現一大堆令人討厭的Bug。而C#中這個var定義的變量在編譯其便推斷出它的類型,并且編譯后的IL代碼中只包含推斷出的類型。
即上面的兩行代碼完全等同物如下代碼:
(圖二,2.jpg)
那么,既然二者等同,我們為什么還要對它的這種“曖昧”情有獨衷?事實上,var關鍵字不僅僅能夠實現我們如上所述的功能,它會成為你在使用C#3.5進行編程時非常熟悉的一個朋友,記住這個“匿名類型(Anonymous Type)”,也記住這個“本地類型推斷(Local Type Reference)”。
二、告訴C#3.5,我們喜歡它纖細的身材——自動屬性(Automatic Properties)
還記得我們在C#1.1和C#2.0寫類的屬性時定義的那個小小的私有變量么?甚至有些人還因為私有變量是否應該和屬性定義在一起而展開了爭論。那么,現行社會流行的“減肥”這個詞也可以應用到我們的程序代碼上來。
C#3.5為我們提供了自動屬性(Automatic Properties),看如下代碼:
(圖三,3.jpg)
很奇怪么?get和set關鍵字均沒有我們以前所熟悉的return value;和_privateField=value;這樣的字眼。事實上,這就是我們的這善解人意的代碼編譯器為我們提供的最新功能自動屬性。編譯器會為我們定義的Name屬性自動生成一私有變量來保存其值。于是,我們原來需要至少三行才能完成的代碼現在僅需一行便輕松完成了。
不過,它有自身的局限性,比如說不能在用自動屬性定義的屬性中加邏輯判斷,get和set必須成對出現等。然而,筆者相信并非我們所有的屬性均要加上邏輯判斷吧?那么,就請去嘗試自動屬性為我們帶來的便利。
三、奇怪的“=>”符號——lambda表達式
習慣C#編程的您在C#2.0及其以前見到過這個符號”=>”么?這又是一新特性,我們可以將它讀作”lambda表達式”。
C# 2.0 通用使用匿名方法引入了"傳遞指針到特定代碼"作為參數的功能。這是一個功能強大的概念,但是這種方式您實際傳遞的是方法的一個指針,而不是代碼塊。那個引用指向編譯時生成的強類型代碼。使用泛型,您可獲得更大靈活性,但是對泛型類型難以應用標準操作符 。C# 3.0 引入 lambda 表達式,它允許使用更簡練的語法來定義匿名方法。
看如下代碼片斷:
(圖四,4.jpg)
且不說其他部分意義,單來看我們.Where括號之中的部分,c=>c.Address==City.Heze這段代碼,我們可以將它理解為,給定c,返回c.Address==City.Heze的記錄集,此處就是lambda表達式的應用之一,它廣泛應用于我們下期即將介紹的LINQ(Language Integerated Query)中。
四、為我們的愛加上更為自由的翅膀——擴展方法
熟知Web編程的朋友們應該對如下這段代碼很熟悉:
(圖五,5.jpg)
其中ReplaceUnSafeChars是一個進行字符器過濾的函數,將傳入的字符串中的非法字符過濾,返回一合法的字符串,它通常用于用戶向某一數據處理頁面提交數據時,為了防止SQL注入或者其他非法入侵而進行的一項工作。為此我們不厭其煩地寫類庫,在某一項目的解決方案中添加進來自己過濾函數。這種方式是不錯,可是,能不能有一種方式讓我們更為方便,讓我們寫出的代碼更為優雅?
設想,如果我們能夠對系統中定義的數據類型進行擴展,給它增加上我們自己的方法,那豈不是我們可以像strID.ToSring()那樣來實現我們自己的過濾方法?
不錯,想法有了,自然C#也不會讓我們失望——擴展方法(Extension Methods)為我們來解決這一問題。如下圖我們定義一個類:
(圖六,6.jpg)
注意,該類為靜態類,并且其中的方法Name為靜態方法,其參數o為object類型,并且有關鍵字this進行修飾。以上這些,就是為系統類型進行擴展時的必備條件。在定義了該類的同一命名空間下的其他類中即可對所有類型使用該Name方法來獲取它的ToString()之后的值。我們看編譯器是如何來表示的:
(圖7,7.jpg)
我們看到,編譯器強大的智能提示功能給我們的提示是(extension) string object.Name(),這是因為我們是對object類進行了擴展,故我們可以對任何類型使用擴展方法Name。
這雖然并不是一個十分大的改動,可是對于我們在代碼上的可讀性及實用性都會有很大的幫助。我們習慣了從左到右的閱讀方式,習慣了在打”.”時編譯器給出智能提示,所以我們也會毫無理由的習慣“擴展方法”。
要注意,對于值類型的變量進行擴展是MS推薦的,可是對于引用類型的變量進行擴展卻并未被推薦,因為對于所有的調用都要創建一個對象的拷貝,而這個對象拷貝的創建的花銷是我們所不敢隨意忽略的。
五、令人心動的LINQ
您想過在代碼中不寫SQL語句就實現對數據庫的操作么?當然,筆者并不是指那種通過拖拽數據源控件如SQLDataSource等然后加個GridView或者FormView就去實現對數據的顯示、更新的操作。假如有一種工具能夠讓將我們數據庫中的表映射為對象,而且映射這一工作能夠自動完成,然后我們就可以通過對這些映射過來的對象進行操作,從而實現對數據表的操作了。
正如筆者上面所說,想法有了,就可以實現。事實上,LINQ并不是屬于C#的,更不能說是C#3.5的特性了。不過筆者在這里提出,主要是因為它實在太令人興奮而且C#3.5中的編程如果沒有了對LINQ的使用代碼就會遜色許多。
上述兩段作為您的“開胃菜”,僅令您心動是遠遠不夠的,讓我們近距離接觸一下LINQ——語言集成查詢(Language Integerated Query)。
筆者以LINQ對數據庫的操作來對LINQ做一下大概的介紹。
LINQ to SQL 是O/RM(對象關系映射)在.NET Framework(Visual Studio 2008)中的的一種實現,它允許你用.NET 的類來生成一個關系型的數據庫。然后你可以用LINQ對從該對象中對數據庫進行查詢,更新/插入/刪除。
LINQ to SQL完全支持事務,視圖和存儲過程。它還提供了一種方便地在你的數據模型中對集合數據驗證和業務邏輯規則的進行驗證的方法。
它的基本語法from… in..select是顯得如此優雅,令我不得不為其用如此簡潔的代碼實現我們以往需要寫數行甚至數十行才能夠實現的功能感到興奮。還記得我們在上面介紹“=>”lambda表達式時提供的那個小例子么?
(圖8,8.jpg)
這就是最簡單的LINQ實現。其中customers可以是我們從數據庫中映射過來的對象,也可以是我們自己定義的某類的實例。它實現的功能是從customers對象實例中查找出所有的Address為Heze的實例,返回值IEnumerable<Customer>類型。LINQ可以實現對所有實現了IEnumuerable接口的對象進行查詢
事實上,LINQ不僅可以to DataSet,也不僅可以to SQL,也不僅可以to XML,筆者認為,LINQ是可以to Everything的。
六 結語
以上僅僅是給筆者很大觸動并且打動了筆者心的若干功能的一部分,限于篇幅筆者不能一一進行展開,望讀者見諒。筆者將在后續的文章中與您分享更多的知識與經驗。
轉載于:https://www.cnblogs.com/hanxianlong/archive/2008/05/15/1196459.html
總結
以上是生活随笔為你收集整理的把我的爱送给你――C#3.5(这题目似乎写错了)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: pandas 数据怎样实现行间计算
- 下一篇: 阳江海滩景色一瞥