類型系統
值類型 vs 參考類型
- 值類型:儲存在堆疊,包含資料本身。
struct、enum、基本型別(int, bool, double 等)。
- 參考類型:儲存在堆積,變數存放參考(指標)。
class, string, array, delegate, interface。
型別轉換
| 方式 | 行為 | 失敗時 |
(T)obj 強制轉型 | 編譯期通過,執行期檢查 | 拋 InvalidCastException |
obj as T | 僅參考類型/可為 null 的值類型 | 回傳 null,不拋例外 |
Convert.ToXxx() | 支援標準轉換,null 轉為預設值 | 拋 FormatException 等 |
類別結構
建構函式
class MyClass
{
public MyClass() { } // 實例建構函式
static MyClass() { } // 靜態建構函式:型別首次使用前執行一次,初始化靜態欄位
}
靜態 vs 實例成員
- 靜態:屬於型別,透過
TypeName.Member 存取。不可存取實例成員。
- 實例:屬於物件,需
new 建立。可存取靜態與實例成員。
繼承與密封
- 單一繼承:
class Child : Base
sealed class:不可被繼承。
abstract class:不可實例化,可含抽象成員(無實作)。
常數 vs 唯讀欄位
| 特性 | const | readonly |
| 初始化時機 | 編譯期(必須為常值運算式) | 執行期(建構函式中) |
| 靜態性 | 隱含 static | 預設實例,可加 static |
| 適用場景 | 真正不變的值(如 Math.PI) | 執行期才能決定的值(如螢幕解析度、組態讀取) |
方法進階
參數修飾詞
ref:呼叫端必須初始化,雙向傳遞。
out:呼叫端無需初始化,方法內必須指派值,單向輸出。
params:參數陣列,呼叫端可傳入 0~N 個引數或陣列。
多載 vs 覆蓋 vs 隱藏
| 概念 | 關鍵字 | 多型 | 說明 |
| 多載 | — | 否 | 同名、不同參數列表(回傳型別不算) |
| 隱藏 | new | 否 | 派生類定義同名成員,基類成員被遮蔽(早期繫結) |
| 覆蓋 | virtual / override | 是 | 基類 virtual,派生類 override(晚期繫結) |
屬性與索引器
class Person
{
private string _name;
public string Name
{
get => _name;
set => _name = value ?? throw new ArgumentNullException();
}
// 索引器:讓物件像陣列一樣存取
private string[] _phones = new string[3];
public string this[int index]
{
get => _phones[index];
set => _phones[index] = value;
}
}
介面
- 定義契約:方法、屬性、事件、索引器(皆隱含
public,不可寫存取修飾詞)。
- 類別可實作多個介面,實現「多重繼承」效果。
- 顯式實作:
void IInterface.Method() { } 解決同名衝突,只能透過介面參考呼叫。
委派與事件
委派
public delegate void NotifyHandler(string message); // 宣告委派型別
// 使用
NotifyHandler handler = msg => Console.WriteLine(msg);
handler += msg => Debug.WriteLine(msg); // 多播委派
handler("Hello"); // 依序呼叫所有目標
事件
public class Publisher
{
public event EventHandler OnCustomEvent;
protected virtual void RaiseEvent(CustomEventArgs e)
{
OnCustomEvent?.Invoke(this, e); // 空條件運算子,執行緒安全
}
}
public class Subscriber
{
public void Subscribe(Publisher p)
{
p.OnCustomEvent += (s, e) => { /* 處理 */ };
}
}
泛型
public class Repository<T> where T : class, new()
{
public T GetById(int id) => /* ... */;
public void Add(T entity) => /* ... */;
}
約束關鍵字:class(參考型別)、struct(值型別)、new()(公用無參建構函式)、BaseClass(繼承自)、IInterface(實作介面)。
異常處理
try
{
// 可能拋出例外的程式碼
}
catch (IOException ex) when (ex.HResult == -2147024864) // 條件捕捉 C# 6+
{
// 檔案不存在
}
catch (Exception ex)
{
// 記錄並重新拋出或處理
throw; // 保留堆疊追蹤
}
finally
{
// 清理資源(關閉檔案、釋放鎖定)
}
反射
Type t = typeof(MyClass); // 或 obj.GetType()
foreach (var m in t.GetMethods(BindingFlags.Public | BindingFlags.Instance))
Console.WriteLine(m.Name);
// 動態建立實例並呼叫方法
var obj = Activator.CreateInstance(t);
var method = t.GetMethod("DoWork");
method.Invoke(obj, new object[] { "arg1" });
非安全程式碼
unsafe 區塊允許指標運算。
fixed 釘選記憶體位置,防止 GC 移動。
- 僅限值型別、陣列、字串;需專案設定「允許不安全程式碼」。
互操作
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern int MessageBox(IntPtr hWnd, string text, string caption, int type);
// 呼叫
MessageBox(IntPtr.Zero, "Hello", "P/Invoke", 0);
結語
本文涵蓋 C# 核心語法與概念,適合作為速查手冊。實務開發中,善用 IDE 智慧提示、靜態分析工具與單元測試,能更高效地寫出正確、可維護的程式碼。