概略來說,如果你觀察 C、C++、C# 這幾門程式語言,會發現一個明顯的差異:
- C 程式由一組函式與資料型別構成
- C++ 程式由一組函式與類別構成
- 而 C# 程式的核心本質,則是一連串的型別宣告
任何 C# 可執行檔(EXE)或動態連結函式庫(DLL)的原始碼,都是由一條或多條型別宣告所組成。
DLL 檔案沒有 Main 程式進入點;但可執行檔(EXE)的原始碼當中,至少必須宣告一個類別,且該類別內要存在名為 Main 的方法做為程式啟動入口。
大型軟體專案的原始碼往往包含成千上萬種型別(例如各類類別),且專案通常由多位開發者分工維護,每人負責不同模組,很容易出現同名型別衝突。該如何解決名稱重複的問題?這時候就會用到前面介紹過的「命名空間」。
命名空間(namespace) 的作用是把多個相關的型別宣告分類歸組,並給予這一整組型別一個統一的識別名稱。由於整支程式本身就是一群相互關聯的型別宣告,開發者通常會自訂命名空間,將專案所有型別都定義在該空間內。
簡單解釋命名空間:替多個類別加上一個群組標籤,其他區域的程式若要存取這些類別,就必須連同該群組名稱一併寫上。
舉個生活化的例子:同一個班級裡如果有兩位姓名完全相同的學生,老師與同學光靠名字無法區分兩人,這時就會加上群組標示做區別,好比A組的TOM與B組的TOM;這裡的A、B就等同於命名空間的作用。
下方程式碼示範一支包含三筆型別宣告的程式,所有型別都定義在名稱為 MyProgram 的命名空間當中。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HelloDemo // 宣告命名空間
{
class A // 宣告型別A(類別)
{
void Fun1() //函式
{
// 程式邏輯
}
}
class B // 宣告型別B(類別)
{
void Fun1() //函式
{
// 程式邏輯
}
}
class C // 宣告型別C(類別)
{
static void Main(string[] args) //Main 程式進入點
{
double pi = 3.14;
string webSite = "foxdevelop.com";
Console.WriteLine($"The Pi is {pi} and the website is {webSite}.");
}
}
}
Code language: PHP (php)
後續章節會針對命名空間做完整、詳細的說明。
型別等同樣板
既然 C# 程式根本上就是各式型別宣告的集合,學習 C# 的核心重點就在於學會建立、操作各種型別。首先我們要先弄懂一件事:
什麼是型別(Type)
你可以把型別想像成用來建立資料結構的樣板:它本身並不是實體資料結構,但會規範透過此樣板產生的物件會具備哪些屬性與特徵。
型別僅僅是一張「設計圖」,本身不會佔用記憶體;唯有實體化之後,系統才會配置記憶體空間來存放資料。
型別就像一張建築藍圖,我們透過這張藍圖產生實體物件。好比房子的設計圖,同一張圖可以蓋出無數棟獨立房屋。
每一種型別都由以下三個要素定義而成:
- 名稱
- 存放成員資料的結構
- 可執行行為與限制條件
C# 當中萬物皆型別,連內建基礎資料型別也不例外。
以下舉兩種內建型別做說明:short 與 int。
其結構規格如下:
| short 型別 | int 型別 |
|---|---|
| 名稱:short | 名稱:int |
| 結構:佔用 2 位元組 | 結構:佔用 4 位元組 |
| 行為:16 位元整數 | 行為:32 位元整數 |
- 名稱:用來辨識該型別(
int、string、自訂類別名稱皆屬此類) - 儲存結構:定義記憶體占用大小、欄位配置方式(例如
short固定占用 2 位元組) - 行為限制:規範此型別支援的運算、數值範圍、內建方法(例如
int可執行加減乘除,數值範圍為-2^31 ~ 2^31-1)
實體化(Instantiate)
透過型別樣板搭配 new 關鍵字,建立一個能實際使用的資料物件
物件(object) = 實例(instance)
以前面提到的 int、short 為例,我們可以透過這兩種型別建立實例。下方範例中的 pi、age、nums,便是分別由 double、int、short 幾種型別產生的實例。
namespace HelloDemo
{
class Program
{
static void Main(string[] args)
{
double pi = 3.14;
int age = 12;
short nums = 23;
}
}
}Code language: JavaScript (javascript)
C# 裡所有變數、資料毫無例外都是某個型別的實例,不存在沒有對應型別的資料。
可以參考上面那段示範程式
範例中的 class C 是做為程式進入點的類別,完全符合可執行檔的規範:
- 屬於
MyProgram命名空間底下自訂的型別 - 內含靜態無回傳值的
Main方法,做為程式啟動入口
C# 不只有 class 一種型別
C# 所有可宣告的型別:類別(class)、結構(struct)、介面(interface)、列舉(enum)、委派(delegate)、記錄型別(record)
BCL(Base Class Library,基礎類別函式庫):.NET 內建標準函式庫,提供 int、short、string、List<T> 等系統預設型別,開發者可直接實體化使用。
型別宣告