飛艷小屋

          程序--人生--哲學(xué)___________________歡迎艷兒的加入

          BlogJava 首頁(yè) 新隨筆 聯(lián)系 聚合 管理
            52 Posts :: 175 Stories :: 107 Comments :: 0 Trackbacks

          都說(shuō)在.NET里,.NET framework和CLR是應(yīng)用運(yùn)行的基礎(chǔ)。那么VB.NET和C#是不是就完全一樣,只是語(yǔ)法不同嗎?

          一、C#

          --- 像VB一樣簡(jiǎn)單,像C++一樣強(qiáng)大的新語(yǔ)
          C#是第一流的面向組件的語(yǔ)言
          由 Turbo Pascal, Delphi, and Visual J++的首席設(shè)計(jì)師Anders Hejlsberg 傾心3年設(shè)計(jì)
          所有的語(yǔ)言元素都是真正的對(duì)象
          開(kāi)發(fā)強(qiáng)壯和可重用的軟件
          所有的.NET Framework中的基類庫(kù)(Base Class Library)都由C# 編寫


          二、VB.NET

          --- 完全面向?qū)ο蟮腂ASIC語(yǔ)言

          1.新語(yǔ)言特性
          完全面向?qū)ο蟥C? 繼承(Inheritance), 重載(overloading), 共享的成員, 結(jié)構(gòu)化異常處理
          強(qiáng)壯的語(yǔ)言 –? 嚴(yán)格的類型檢查, 變量聲明時(shí)初始化,支持垃圾收集(Garbage collection)
          強(qiáng)大 –? 支持委托(Delegates), free threading,Variant 數(shù)據(jù)類型被 Object 代替
          2.與VB6一致的語(yǔ)法

          三、2者的區(qū)別?
          1.語(yǔ)法上的差異
          ??????? 例如循環(huán)的寫法

          VB.NET

          For I = 1 To 10
          ?? ‘ for loop
          Next I

          C#

          For (i=1;i<11;i++) {
          // for loop
          }
          另外Visual Basic 對(duì)大小寫不敏感,而C#是大小寫敏感的。

          2.C# 具有但 Visual Basic 不具有的特性
          ?????????? 指針, 移位操作符, 內(nèi)嵌的文檔(XML)
          ????????? 重載操作符

          3.Visual Basic具有但 C# 不具有的特性

          更豐富的語(yǔ)法: Events, Try…Catch, Select…Case, 實(shí)現(xiàn) Interface
          后期綁定(Late binding), 動(dòng)態(tài)數(shù)組, 模塊(modules), 可選參數(shù), 參數(shù)屬性(parameterized properties)
          后臺(tái)編譯


          C#與VB.net間移植的技巧


          按理說(shuō),這兩種語(yǔ)言沒(méi)有什么移植的必要,因?yàn)樗麄兩傻拇a可以完全通用。但是如果一個(gè)工程基本上是VB寫成的,卻需要少許已經(jīng)存在的C#過(guò)程,用組件并不是一種效率很高的辦法。就算是學(xué)習(xí)C#或VB,學(xué)會(huì)他們之間的移植可以雙倍的利用已經(jīng)存在的代碼(如好玩的Donkey.net就只有VB版)。
          ??
          ? 有人比較過(guò)這兩種語(yǔ)言,得出的結(jié)論是他們很相似。但即便是這樣,VB初學(xué)者看到諸如((Button)sender).Text = “啟動(dòng)”;之類的語(yǔ)法不知道如何移植到VB,而C#初學(xué)者看到Handles Button1.Click等語(yǔ)法也會(huì)為移植而感到頭痛。下面就看看他們最難移植的部分:
          ??
          ? 1、Option語(yǔ)句。VB的Option語(yǔ)句可以打開(kāi)或關(guān)閉變量聲明檢查和類型轉(zhuǎn)換檢查。尤其是Option Strict被關(guān)閉后,VB變成弱類型語(yǔ)言,很多類型轉(zhuǎn)換都是自動(dòng)的,移植到C#中會(huì)產(chǎn)生無(wú)數(shù)錯(cuò)誤。因此,如果要將帶有Option Strict Off語(yǔ)句的VB程序移植到C#,最好先在VB中將Option Strict打開(kāi),然后把所有類型轉(zhuǎn)換出錯(cuò)的地方變成強(qiáng)類型轉(zhuǎn)換,然后再進(jìn)行移植。
          ??
          ? 2、類型轉(zhuǎn)換。VB提供了很多類型轉(zhuǎn)換函數(shù)型運(yùn)算符,如CInt(), CSng(), CStr()等,在C#中只要用(int) , (float), (String)即可。然而如果不是標(biāo)準(zhǔn)類型,如下面的C#語(yǔ)句:
          ??
          ? ((System.Button)sender).Text = “啟動(dòng)”;
          ??
          ? 就要使用VB的函數(shù)型運(yùn)算符CType來(lái)實(shí)現(xiàn)。上面的代碼正確的移植方法是:
          ??
          ? CType(sender, System.Button).Text = “啟動(dòng)”
          ??
          ? 千萬(wàn)不要使用某些人推薦的,將Option Strict關(guān)閉,然后用后期綁定調(diào)用sender對(duì)象的方法,這根本不符合程序移植不能改變本質(zhì)的要求。
          ??
          ? 3、修飾符和屬性標(biāo)簽。VB和C#的修飾符是完全對(duì)等存在的,但是拼寫往往不同,給移植帶來(lái)了很多麻煩,尤其是表示相同意思的關(guān)鍵字從字面理解完全不同的時(shí)候。下面就給出了VB和C#對(duì)應(yīng)的關(guān)鍵字:
          ??
          ? VB
          ?? C#
          ?? VB
          ?? C#
          ??
          ? Inherits
          ?? :
          ?? Implements
          ?? :
          ??
          ? MustInherit
          ?? abstract
          ?? NotInheritable
          ?? sealed
          ??
          ? Overridable
          ?? virtual
          ?? NotOverridable
          ?? sealed
          ??
          ? MustOverride
          ?? abstract
          ?? Overrides
          ?? override
          ??
          ? [Overloads]
          ?? 無(wú)
          ?? Shadows
          ?? new
          ??
          ? Shared
          ?? static
          ?? Public
          ?? public
          ??
          ? Protected
          ?? protected
          ?? Friend
          ?? internal
          ??
          ? Protected Friend
          ?? protected internal
          ?? Private
          ?? private
          ??
          ? Static
          ?? 用別的方法實(shí)現(xiàn)
          ?? ByVal
          ?? 無(wú)
          ??
          ? ByRef
          ?? ref
          ?? Optional
          ?? 無(wú)
          ??
          ? ParamArray
          ?? params
          ?? 無(wú)法實(shí)現(xiàn)
          ?? unsafe
          ??
          ? 無(wú)法實(shí)現(xiàn)
          ?? fixed
          ??
          ??
          ? 可以看出,VB的關(guān)鍵字比較長(zhǎng),而且使用上也比C#更加嚴(yán)格。從C#向VB移植的時(shí)候,要分外注意哪些VB有而C#沒(méi)有的關(guān)鍵字以及在C#拼寫相同,在VB中拼寫不同的關(guān)鍵字(如MustOverride和MustInherit)。有些關(guān)鍵字如unsafe,如果C#使用了他們,將無(wú)法移植到VB中。好在這些關(guān)鍵字在商業(yè)應(yīng)用中并不常用。
          ??
          ? 屬性標(biāo)簽在這兩種語(yǔ)言中非常的相似,移植上應(yīng)該沒(méi)有任何難度,只要知道在C#中用方括號(hào)[]表示屬性標(biāo)簽,而在VB中用的是尖括號(hào)<>。另外,如果要用名稱結(jié)合傳遞參數(shù),C#直接使用=號(hào),而VB使用:=(冒號(hào)和等號(hào))。
          ??
          ? 4、委派類型。委派類型就是安全的函數(shù)指針類型。在C#中,難以分辨是函數(shù)指針在工作還是函數(shù)本身在工作,因?yàn)樗麄兊恼Z(yǔ)法相同。當(dāng)要為一個(gè)委派類型的變量復(fù)制的時(shí)候,直接等于一個(gè)函數(shù)即可,如:
          ??
          ? public delegate void FuncType(Object e)
          ??
          ? ...
          ??
          ? FuncType func;
          ??
          ? func = new FuncType(this.SampleFunction1);
          ??
          ? //調(diào)用
          ??
          ? func(something);
          ??
          ? //換指向另外一個(gè)函數(shù)
          ??
          ? func = this.SampleFunction2
          ??
          ? 然而VB中,委派類型就像是一般的對(duì)象,有它的方法,與函數(shù)本身明顯不同。你不能將過(guò)程的名字直接賦給一個(gè)委派類型的對(duì)象,而必須使用AddressOf運(yùn)算符,下面的例子就是上文C#程序的VB版,注意那些實(shí)現(xiàn)不同的地方:
          ??
          ? Public Delegate Sub FuncType(ByVal e As Object)
          ??
          ? ...
          ??
          ? Dim func As FuncType
          ??
          ? func = New FuncType(AddressOf Me.SampleFunc1)
          ??
          ? ‘ 調(diào)用
          ??
          ? func.Invoke(something)
          ??
          ? ‘ 換指向另外一個(gè)函數(shù)
          ??
          ? func = AddressOf Me.SampleFunction2
          ??
          ? 5、事件處理。這是兩種語(yǔ)言最大的差別之一,VB傳承以前版本強(qiáng)大的事件處理機(jī)制,許多語(yǔ)法都比C#更加靈活。好在無(wú)論什么情況,他們之間都是可以互相移植的。
          ??
          ? 對(duì)于事件定義,兩種語(yǔ)言都是一個(gè)委派類型加一個(gè)事件屬性,如:
          ??
          ? [C#]
          ??
          ? public delegate void MyEventHandler(Object sender, EventArgs e);
          ??
          ? public event MyEventHandler MyEvent;
          ??
          ? [Visual Basic]
          ??
          ? Public Delegate Sub MyEventHandler(ByVal sender As Object, ByVal e As EventArgs)
          ??
          ? Public Event MyEvent As MyEventHandler
          ??
          ? VB還支持另外一種更加緊湊的定義方法,只有一條語(yǔ)句:
          ??
          ? Public Event MyEvent(ByVal sender As Object, ByVal e As EventArgs)
          ??
          ? 移植的時(shí)候,要把參數(shù)部分分離出來(lái),成為一個(gè)委派類型,再按照普通方法定義事件即可。
          ??
          ? 關(guān)于事件響應(yīng),C#與Delphi等語(yǔ)言一樣,是動(dòng)態(tài)綁定事件過(guò)程的,其語(yǔ)法類似于下:
          ??
          ? internal MyClass myobj;
          ??
          ? ...
          ??
          ? myobj = new MyClass();
          ??
          ? ...
          ??
          ? myobj.MyEvent += this.myobj_MyEvent;
          ??
          ? ...
          ??
          ? protected void myobj_MyEvent(Object sender, EventArgs e)
          ??
          ? {
          ??
          ?? //語(yǔ)句
          ??
          ? }
          ??
          ? 可以看到,C#是利用運(yùn)算符連接事件過(guò)程和事件屬性的。之后,還可以用-=運(yùn)算符解除事件過(guò)程與事件屬性的綁定。VB不支持運(yùn)算符重載,但仍然支持這種動(dòng)態(tài)綁定的事件過(guò)程,方法是使用AddHandler和RemoveHandler關(guān)鍵字。如上面黑體部分可以移植為:
          ??
          ? AddHandler myobj.MyEvent, AddressOf Me.myobj_MyEvent
          ??
          ? 解除綁定的語(yǔ)法與此類似,只是關(guān)鍵字為RemoveHandler而已。一定不要忘記過(guò)程前面還有一個(gè)AddressOf關(guān)鍵字!
          ??
          ? 動(dòng)態(tài)綁定的事件過(guò)程工作起來(lái)比較慢,VB支持一種更快的靜態(tài)綁定事件過(guò)程。一旦為對(duì)象設(shè)置了靜態(tài)的事件過(guò)程,就不能解除綁定,一般大多數(shù)情況都是如此。語(yǔ)法如下:
          ??
          ? ‘ 定義變量時(shí)使用WithEvents關(guān)鍵字
          ??
          ? Friend WithEvents myobj As MyClass
          ??
          ? ‘ 直接書寫事件過(guò)程,注意Handles的語(yǔ)法:
          ??
          ? Protected Sub myobj_MyEvent(ByVal sender As Object, ByVal e As EventArgs) _
          ??
          ? Handles myobj.MyEvent
          ??
          ?? ‘ 語(yǔ)句
          ??
          ? End Sub
          ??
          ? 它表示myobj_MyEvent這個(gè)過(guò)程僅僅響應(yīng)myobj.MyEvent這個(gè)過(guò)程。如果一個(gè)過(guò)程要響應(yīng)很多個(gè)事件,把他們列在Handles后面,用逗號(hào)隔開(kāi),如Handles Event1, Event2, ...
          ??
          ? 遇到這種情況,要看清Handles后面的所有對(duì)象和事件,將它們一一改寫成動(dòng)態(tài)綁定的語(yǔ)句:
          ??
          ? Protected Sub XXX(...) Handles myobj1.MyEvent, myobj2.MyEvent
          ??
          ? ==>
          ??
          ? myobj1.MyEvent += this.XXX;
          ??
          ? myobj2.MyEvent += this.XXX;
          ??
          ? ...
          ??
          ? protected void XXX(...){}
          ??
          ? 當(dāng)事件比較多時(shí),C#顯著變得比較麻煩,幸好一個(gè)過(guò)程響應(yīng)一大堆事件的情況也不太多(不過(guò)我就編寫過(guò)一個(gè)過(guò)程相應(yīng)8個(gè)事件,移植起來(lái)好麻煩!)。原則上說(shuō),將靜態(tài)事件過(guò)程移植為動(dòng)態(tài)事件過(guò)程并沒(méi)有完全遵守移植的規(guī)定,但我估計(jì)他們實(shí)現(xiàn)的原理不會(huì)相差太多,所以也不用擔(dān)心。
          ??
          ? 6、異常處理。VB支持兩種形式的異常,即.net框架的異常和VB自己的錯(cuò)誤號(hào)碼。而C#只支持第一種。用到VB自己的錯(cuò)誤號(hào)碼的程序幾乎無(wú)法移植到C#中,所以應(yīng)該盡量使用.net框架的異常,如下面VB語(yǔ)句:
          ??
          ? Try
          ??
          ?? ‘ 發(fā)生錯(cuò)誤的代碼
          ??
          ? Catch When Err.Number = 52
          ??
          ?? ‘ 解決錯(cuò)誤的代碼
          ??
          ? End Try
          ??
          ? 這段代碼無(wú)法直接移植到C#中,只有用Exception對(duì)象取代Err對(duì)象獲得異常信息,才能順利移植。另外VB的When語(yǔ)句帶給Try語(yǔ)句十分靈活的用法,必須用很高的技巧才能在C#中實(shí)現(xiàn),這就需要具體問(wèn)題具體分析了。
          ??
          ? VB支持Exit Try語(yǔ)句,可以直接從Try塊或Catch塊跳轉(zhuǎn)到Finally塊。C#沒(méi)有提供類似的語(yǔ)法,可以用以下技巧:
          ??
          ? [Visual Basic]
          ??
          ? Try
          ??
          ?? ‘ 一些語(yǔ)句
          ??
          ?? Exit Try
          ??
          ? Finally
          ??
          ?? ‘ 一些語(yǔ)句
          ??
          ? End Try
          ??
          ? [C#]
          ??
          ? try
          ??
          ? {
          ??
          ?? //一些語(yǔ)句
          ??
          ?? goto __leave;
          ??
          ? }
          ??
          ? finally
          ??
          ? {
          ??
          ?? //一些語(yǔ)句
          ??
          ? }
          ??
          ? __leave: //別忘了這里還有哦!
          ??
          ? 總之是利用了finally塊無(wú)法跳過(guò)的特征,用goto語(yǔ)句模擬了Exit Try語(yǔ)句。
          ??
          ? 如果VB程序用的是VB特有的On Error GoTo語(yǔ)句實(shí)現(xiàn)的錯(cuò)誤處理,問(wèn)題就麻煩了。代碼可能在過(guò)程中上下跳躍,無(wú)法預(yù)料語(yǔ)句的執(zhí)行方式。這種代碼理解起來(lái)就頭痛,更不要說(shuō)移植了。總體來(lái)說(shuō),把所有語(yǔ)句統(tǒng)統(tǒng)轉(zhuǎn)移到try塊中,然后用catch一一處理錯(cuò)誤。遇到要返回(Resume語(yǔ)句)的時(shí)候,只好Copy代碼了。反正不是一件容易的事情,慢慢改就是了。
          ??
          ? 7、模塊。VB支持模塊,C#不支持。但也沒(méi)有關(guān)系,只要在C#中制造一個(gè)abstract類,共享所有成員,就和模塊一樣了。當(dāng)然不能像VB一樣直接訪問(wèn)模塊中的成員,需要用到“類名.成員名”的用法。
          ??
          ? 8、接口。C#在接口方面也沒(méi)有VB強(qiáng)大(怎么這么重要的功能也不做得好一點(diǎn)?),VB采用Implements語(yǔ)句結(jié)合接口的成員和類的實(shí)現(xiàn)成員,而C#是用名稱結(jié)合。因此VB就可以隨便修改實(shí)現(xiàn)成員的訪問(wèn)級(jí)別和名稱,而C#就不能改名稱。將C#移植為VB時(shí),最好利用VB.net編輯器直接實(shí)現(xiàn)接口,比較簡(jiǎn)單。把VB移植為C#時(shí),就必須把改過(guò)的名字都改回來(lái),遇到名字沖突就更討厭了(這時(shí)候我?guī)缀醪幌朐僖浦矠镃#了)。給一個(gè)例子:
          ??
          ? [Visual Basic]
          ??
          ? Public Class Class1 : Implements IMyInterface
          ??
          ?? Public Sub DoSth() Implements IMyInterface.Method1
          ??
          ?? End Sub
          ??
          ? End Class
          ??
          ? [C#]
          ??
          ? public class Class1 : IMyInterface
          ??
          ? {
          ??
          ?? public void Method1()
          ??
          ? {
          ??
          ? }
          ??
          ? }
          ??
          ? 9、運(yùn)算符重載。這會(huì)遇到VB頭痛了,既然VB不支持運(yùn)算符重載,那么就必須用子程序和函數(shù)來(lái)模擬運(yùn)算符。比如建立Plus和Minus方法模擬+和-的運(yùn)算。當(dāng)然還是有很多情況(比如遇上了explicit和implicit語(yǔ)句)就真的沒(méi)有辦法了,只好不移植了。運(yùn)算符重載是一個(gè)很不錯(cuò)的功能,它能使很多操作簡(jiǎn)單地完成,如果VB支持它,就真的是完美語(yǔ)言了。
          ??
          ? 好了,想必最麻煩的地方已經(jīng)說(shuō)完了,剩下的就是簡(jiǎn)單的Copy了。雖然有些地方還沒(méi)有說(shuō)清楚,但基本上闡明了兩種語(yǔ)言的不同(一看,不同還挺多的吧),反正也不用移植大的工程,了解這些內(nèi)容主要是為了利用雙倍的利用已經(jīng)存在的代碼,但愿本文對(duì)你有用。

          posted on 2006-06-06 15:17 天外飛仙 閱讀(526) 評(píng)論(0)  編輯  收藏 所屬分類: .net
          主站蜘蛛池模板: 涿鹿县| 偃师市| 邢台县| 景洪市| 夏河县| 错那县| 九江市| 英德市| 沙河市| 青岛市| 昭通市| 巴林右旗| 高雄市| 安陆市| 仁怀市| 沙雅县| 青铜峡市| 绥芬河市| 惠来县| 建瓯市| 襄樊市| 许昌县| 宜阳县| 嘉善县| 曲沃县| 清流县| 太谷县| 东宁县| 榆林市| 澄城县| 新化县| 永定县| 福泉市| 沙洋县| 仁布县| 广宗县| 章丘市| 灵台县| 平邑县| 营山县| 康保县|