C＃与Visual_Basic_.NET的比较

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

## 語言歷史

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

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

## 語言比較

雖然 C# 和 VB.NET 在語法上有相當的不同，但因為都是微軟開發的.NET 框架下的程式語言，而且是由同一個開發團隊進行開發、管理及維護，因此會有不少的共通點。C# 和 VB.NET 會編譯為同一種中介語言，在同一種.NET 框架下的執行期函式庫下執行。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 文字
* date 文字常數，如 `#12/31/2000#`
* `Module` 語句（雖然 C# 的靜態類更容易理解，但靜態類里每個成員都必須顯示聲明為 `static`。）
* 當前檔案匯入模組後，該模組的成員可以無需限定符進行存取。
* `My` 命名空間
* COM 組件和互操作性更強，因為物件類型是執行時繫結的。 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 有不少內建常數，如 `vbCrLf`、`vbTab`。
* 沒有用於修飾參數的 `out` 關鍵字。
* `MyClass` 關鍵字的行為類似於參照最初實現的類的當前實例。`MyClass` 類似於 `Me`，但是對它的所有方法呼叫都被視為方法被 NotOverridable 修飾。
* `MyBase.New` 用來呼叫父類別的建構函式。
* 局部變數自動初始化。
* 方法內的靜態局部變數在方法呼叫多次時可保持原來的值。
* `End` 語句直接終止程式。
* 可對 Lambda 表達式推斷類型，如 `Dim x = Function(n As Integer) n + 1`
* 成員名可以與其所在的類型名相同。

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

* 多行注釋。
* 靜態類。
* C# 和 VB 都可以在專案屬性里開啟或禁用溢位檢查，但 C# 提供 `checked`、`unchecked` 關鍵字進行精細控制。
* 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 將儘可能強制轉換該值。這種自動強制轉換有時會導致意想不到的結果，比如

為了向下相容，`Option Strict` 的預設值是關閉，但微軟建議將其開啟

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

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

* C＃識別碼區分大小寫。
* 可將同一值賦給多個變數：`a=b=c`。

## 兩種語言的 HelloWorld

以下是兩種語言的 HelloWorld：

**VB.NET**

**C#**

## 相關條目