從 C++ 轉向 C#,語法雖然相似,但記憶體模型、型別系統、物件生命週期等核心機制差異極大。本文整理 10 關鍵差異,幫助 C++ 開發者快速建立正確的 C# 思維模型。
C# 不支援類別多重繼承,改用 介面 定義契約:
interface ICar
{
int Speed { get; set; }
void Run();
void Stop();
}
class MyCar : ICar
{
private int _speed;
public int Speed { get => _speed; set => _speed = value; }
public void Run() => Console.WriteLine($"Speed: {_speed}");
public void Stop() => Console.WriteLine("Stopped");
}
一個類別可實作多個介面:class Car : IEngine, IBrake, IAudio
// 一維
int[] arr1 = new int[10];
int[] arr2 = { 1, 2, 3 };
// 多維(矩形陣列)
int[,] matrix = new int[5, 10];
matrix[1, 2] = 5;
// 交錯陣列
int[][] jagged = new int[3][];
jagged[0] = new int[4];
jagged[1] = new int[] { 1, 2, 3 };
陣列隱含繼承 System.Array,擁有 Length、Rank 等屬性。
class IndexerDemo
{
private int[] _data = new int[10];
public int this[int index]
{
get => _data[index];
set => _data[index] = value;
}
}
// 使用
var d = new IndexerDemo();
d[3] = 42;
Console.WriteLine(d[3]);
void ByValue(int x) { x = 777; }
void ByRef(ref int x) { x = 888; }
void ByOut(out int x) { x = 999; } // 呼叫前無需初始化,方法內必指派
void ByParams(params int[] arr) { Console.WriteLine(arr.Length); }
C++ 開發者注意:ref 對應 C++ 的 int&,out 類似 int& 但語意為「輸出」。
object obj = "hello";
if (obj is string s) // 型別測試 + 宣告模式
Console.WriteLine(s.Length);
string str = obj as string; // 失敗回傳 null,不拋例外
// 等同:obj is string ? (string)obj : null
int[] arr = { 1, 2, 3 };
foreach (int i in arr) Console.WriteLine(i);
// 編譯器轉換為 IEnumerator 模式,支援自訂迭代器
class Base { public virtual void Speak() => Console.WriteLine("Base"); }
class Derived : Base { public override void Speak() => Console.WriteLine("Derived"); }
class SealedDerived : Derived { public sealed override void Speak() => Console.WriteLine("Sealed"); }
C++ 預設非虛擬,C# 同樣需 virtual 關鍵字;覆寫必須加 override,編譯器會強制檢查。
class Base { public virtual void Draw() => Console.WriteLine("Base.Draw"); }
class Derived : Base { public new void Draw() => Console.WriteLine("Derived.Draw"); } // 隱藏而非覆寫
Base b = new Derived();
b.Draw(); // 輸出 "Base.Draw"(靜態繫結)
這是 C++ 無對應機制的特有行為,慎用。
class Child : Base
{
public override void Draw()
{
base.Draw(); // 呼叫基底實作
Console.WriteLine("Child.Draw");
}
}
| 特性 | C++ | C# |
|---|---|---|
| 記憶體回收 | 手動 delete / 智慧指標 | 自動 GC(非決定性) |
| 解構子 | ~Class() 確定性呼叫 | 終結子 ~Class() 非決定性,GC 時呼叫 |
| 資源釋放 | RAII 模式 | IDisposable + using 區塊 |
| 非受控資源 | 直接管理 | SafeHandle、GC.SuppressFinalize |
namespace 取代 header 檔,using 導入public int Age { get; set; } 取代 getter/setter 函式List<T> 取代 template,執行期具現化async/await 取代 callback/futurestring?、?.、??、??= 運算子IDisposable 模式處理檔案、資料庫連線等非受控資源nullable 參考類型(專案屬性 `