C# 提供類似 Java 的自動記憶體管理,開發者無需手動釋放記憶體,GC 會追蹤物件參考,並在物件不可觸及時回收。以下範例示範堆疊實作,節點不再被參考時自動回收:
public class Stack
{
private Node first = null;
public bool Empty => first == null;
public object Pop()
{
if (first == null) throw new Exception("Can't Pop from an empty Stack.");
object temp = first.Value;
first = first.Next;
return temp;
}
public void Push(object o) => first = new Node(o, first);
private class Node
{
public Node Next;
public object Value;
public Node(object value) : this(value, null) { }
public Node(object value, Node next) { Next = next; Value = value; }
}
}
// 測試:Push 10 個元素後將堆疊參考設為 null,所有節點變為不可觸及,等待 GC 回收
class Test
{
static void Main()
{
Stack s = new Stack();
for (int i = 0; i < 10; i++) s.Push(i);
s = null; // 此時 s 及其所有 Node 皆符合回收條件
}
}
C# 限制指標使用,但透過 unsafe 關鍵字可在受控區塊中直接操作記憶體,適合高效能、互通性或系統層級程式。編譯需加 /unsafe 參數。
using System;
class Test
{
unsafe static void Locations(byte[] arr)
{
fixed (byte* p = arr) // 固定陣列位置,防止 GC 移動
{
byte* pElem = p;
for (int i = 0; i < arr.Length; i++)
{
byte value = *pElem;
string addr = ((int)pElem).ToString("X");
Console.WriteLine($"arr[{i}] at 0x{addr} is {value}");
pElem++;
}
}
}
static void Main()
{
byte[] arr = { 1, 2, 3, 4, 5 };
Locations(arr);
}
}
unsafe:標示方法/區塊包含指標操作,編譯器允許指標語法。fixed:將受控陣列/字串在記憶體中「釘住」,防止 GC 壓縮堆疊時移動位址,取得穩定指標。byte*:指向 byte 的指標,支援解參考 *、遞增 ++ 等運算。fixed 的陣列可能被移動,導致指標失效。Span<T> / Memory<T>:現代 .NET 提供安全的記憶體切片抽象,多數情況可替代 unsafe。