C#與Visual Basic .NET的比較

C#VB.NET微軟公司開發的.NET框架中,兩種物件導向程式語言,分別衍生自C++語言Visual Basic,因此在語法,註解方式都有許多的差異。

語言歷史

編輯

C#和VB.NET各自有其不同的歷史,在語法上也有很大的差異。C#語法的基礎是衍生自1970年代丹尼斯·里奇貝爾實驗室(AT&T)發展的C語言[1],其中也包括了完全物件導向的C++,許多Java語言語法的基礎也是來自C++語言[2],這也是C#和Java有許多相近之處的原因。

VB.NET是來自1960年代的BASIC語言,是「Beginner's All-purpose Symbolic Instruction Code」的縮寫,一開始BASIC在學校中教授,而且如它的名字所述的,被視為是一個基礎的程式語言。1970年代微電腦的製造商將BASIC用來做電腦系統的程式語言,以及有簡單輸入輸出控制的半作業系統。1980年代微軟也開始使用將一此語言,1990年代發展為Visual basic,用在window系統的快速應用程式開發[3],Visual basic打敗了當時像PowerBuilder等快速應用程式開發工具[4]。雖然Visual Basic如此的成功,但在2000年代初期微軟提出.NET框架及對應的Visual Studio開發平台,而Visual Basic也在第六版(VB6)畫下句點。

語言比較

編輯

雖然C#和VB.NET在語法上有相當的不同,但因為都是微軟開發的.NET框架下的程式語言,而且是由同一個開發團隊進行開發、管理及維護,因此會有不少的共通點[5]。C#和VB.NET會編譯為同一種中介語言,在同一種.NET框架下的執行期函式庫下執行[6]。C#和VB.NET在語言結構上有一些差異,差異主要都是語法上的差異,但不要使用微軟提供,方便和VB6轉換的相容性函式庫,幾乎每一個VB.NET中的指令都有對應的C#的指令,反之亦然。為了延伸其機能,兩種語言也參考同一個.NET框架下的基礎類別。因此大多數用其中一個語言寫的程式可以用語法轉換程式轉換為另一種語言,只有少數例外,而已有許多開源軟體及商業軟體有這類的功能。

語言特性

編輯

從技術角度來看,C#和VB.NET之間的大部分差異都是語法糖。也就是說,大多數特性都存在於兩種語言,但有些任務在一種語言中比另一種語言更容易完成。

存在於Visual Basic .NET但不存在於C#的特性

編輯
  • 可以使用WithEvents結構聲明變數。此結構令程式設計師可以從「類名」下拉式清單中選擇一個對象,然後從「聲明」下拉式清單中選擇一個方法以自動插入方法簽章
  • 自動連接事件。VB.NET支援事件的Handles語法,它將事件處理程式連接到對象變數而不是對象。
  • 使用RaiseEvent關鍵字引發事件,IDE在此關鍵字後會顯示可用的事件列表。RaiseEvent隱式檢查事件處理程式是否為Nothing。(在C#中引發事件在語法上與呼叫過程完全相同,並且需要額外的代碼行來檢查有線事件處理程式)
  • 事件代理被隱式聲明。
  • With ... End With結構內,點運算子前可不寫出對象名。
  • XML文字[7][8]
  • date文字常數,如#12/31/2000#
  • Module語句(雖然C#的靜態類更容易理解,但靜態類里每個成員都必須顯示聲明為static。)
  • 當前檔案匯入模組後,該模組的成員可以無需限定符進行訪問。[9]
  • My命名空間[10]
  • COM組件和互操作性更強,因為對象類型是執行時繫結的。[11] C# 4.0的dynamic關鍵字提供了相同的便利。
  • 可以在專案級別匯入命名空間,這樣一來該專案的每個檔案都可訪問該命名空間。
  • 使用#Const指令定義條件編譯器常數。#Const常數一般在#If語句中使用。
  • 屬性可以攜帶參數。
  • 屬性可以直接按參照(ByRef)傳入方法。在C#里屬性必須先賦值給局部變數,再傳入。
  • 介面里可定義列舉。
  • Case語句可接不等式,如Select x: Case Is >= 3。 (在C#里必須用if ... else實現。)
  • 子類若有與父類別同名的方法,則子類別方法必須被Overloads關鍵字修飾。(C#中缺少此關鍵字可能會導致意外多載)
  • Like運算子支援模式比較。(C#只能訪問Microsoft.VisualBasic.CompilerServices.LikeOperator.LikeString方法)
  • Return語句可省略。也可向當前方法賦值來設定返回值。
  • Visual basic有不少內建常數,如vbCrLfvbTab
  • 沒有用於修飾參數的out關鍵字。
  • MyClass關鍵字的行為類似於參照最初實現的類的當前實例。MyClass類似於Me,但是對它的所有方法呼叫都被視為方法被NotOverridable修飾。
  • MyBase.New用來呼叫父類別的建構函式。
  • 局部變數自動初始化。
  • 方法內的靜態局部變數在方法呼叫多次時可保持原來的值。
  • End語句直接終止程式。
  • 可對Lambda表達式推斷類型,如Dim x = Function(n As Integer) n + 1
  • 成員名可以與其所在的類型名相同。

存在於C#但不存在於Visual Basic .NET的特性

編輯
  • 多行注釋。
  • 靜態類。
  • C#和VB都可以在專案屬性里開啟或禁用溢位檢查,但C#提供checkedunchecked關鍵字進行精細控制。
  • for語句可以有多個條件,如for(int i = 0; i < 10 && somethingTrue; i++)
  • 屬性的getter和setter可以實現不同的介面。VB里必須定義兩個屬性。
  • 隱式介面實現。
  • null條件運算子??返回第一個非null值(如null ?? null ?? 1返回1)。
  • 可在unsafe環境使用指標
  • 條件運算子?: someThingTrueOrFalse ? whenTrue() : whenFalse();

存在於Visual Basic .NET但無法應用到C#的特性

編輯
  • 轉換布林值True到Integer可能會產生-1或1,具體取決於所使用的轉換。
  • 變數賦值和比較使用相同的符號:=。C#用不同的符號:===,這允許在條件語句中先賦值,再比較。
  • VB.NET識別碼不區分大小寫。
  • 當為具有不同資料類型的變數賦值(並且Option Strict未打開時),VB.NET將儘可能強制轉換該值。這種自動強制轉換有時會導致意想不到的結果,比如
Dim i As Integer = "1" '编译器插入一个从String到Integer的转换方法
Dim j As String = 1 '编译器插入一个从Integer到String的转换方法
If i = j Then '编译器插入一个从String到double的转换方法
    MsgBox("Avoid using, but this message will appear!")
End If

為了向下相容,Option Strict的預設值是關閉,但微軟建議將其開啟[12][13]

  • 內建函式Val()的參數可以是null。
  • 有大量內建的類型轉換函式:CInt, CStr, CByte, CDbl, CBool, CDate, CLng, CCur, CObj。

存在於C#但無法應用到Visual Basic .NET的特性

編輯
  • C#識別碼區分大小寫。
  • 可將同一值賦給多個變數:a=b=c

兩種語言的HelloWorld

編輯

以下是兩種語言的HelloWorld

VB.NET

Imports System

Module HelloWorldApp
    ' VB.NET Console 主程序
    Sub Main()
        ' 輸出 Hello World! 至 Console
        Console.WriteLine("Hello World!")
        ' ReadKey 用來暫停避免直接關閉 Console 視窗
        Console.ReadKey()
    End Sub
End Module

C#

using System;

namespace HelloWorldApp
{
    class Program
    {
        // C# Console 主程序
        static void Main(string[] args)
        {
            // 輸出 Hello World! 至 Console
            Console.WriteLine("Hello World");
            // ReadKey 用來暫停避免直接關閉 Console 視窗
            Console.ReadKey();
        }
    }
}

相關條目

編輯
  1. ^ Chistory. Cm.bell-labs.com. [2013-08-18]. (原始內容存檔於2015-02-03). 
  2. ^ History of Java programming language. www.freejavaguide.com. [2013-08-18]. (原始內容存檔於2013-08-14). 
  3. ^ The Birth of Visual Basic. Forestmoon.com. [2013-08-18]. (原始內容存檔於2010-06-07). 
  4. ^ Powersoft History PowerBuilder History. Lannigan.org. [2013-08-18]. (原始內容存檔於2013-09-01). 
  5. ^ Krill, Paul. Microsoft converging programming languages | Developer World. InfoWorld. 2009-02-27 [2013-08-18]. 
  6. ^ Microsoft Intermediate Language. Dotnet-guide.com. [2013-08-18]. (原始內容存檔於2013-06-02). 
  7. ^ Jonathan Allen. Does C# Need VB9's XML Literals?. [2009-01-13]. (原始內容存檔於2009-02-14). 
  8. ^ XML 文本概述 (Visual Basic). [2019-08-26]. (原始內容存檔於2019-08-26). 
  9. ^ DateAndTime.Now Property (Microsoft.VisualBasic). Msdn.microsoft.com. 2015-02-18 [2015-02-24]. (原始內容存檔於2015-09-28). 
  10. ^ Development with My (Visual Basic). Msdn.microsoft.com. 2015-02-18 [2015-02-24]. (原始內容存檔於2015-01-10). 
  11. ^ Early vs. Late Binding. Visualbasic.about.com. [24 February 2015]. (原始內容存檔於2015-02-25). 
  12. ^ Option Strict Statement. Msdn.microsoft.com. 2015-02-18 [2015-02-24]. (原始內容存檔於2015-01-14). 
  13. ^ GetDotNetCode.com:Option Strict On. Getdotnetcode.com. [24 February 2015]. (原始內容存檔於2012-03-13).