類 (class) 是 C# 面向對象編程的基石,封裝狀態 (字段) 與行為 (方法/屬性/事件等),支持繼承、多態、封裝三大特性。本文系統梳理類聲明語法、實例生命週期、成員分類、可訪問性、基類與派生、字段/方法/屬性/索引器/事件/運算符/構造函數/析構函數全成員體系,附帶代碼範例與最佳實踐。
// 完整類聲明語法
[attributes] [modifiers] class ClassName [: BaseClass] [interfaces] {
// 類體:成員聲明
}
// 示例:Point 類
public class Point {
// 字段
public int X, Y;
// 構造函數
public Point(int x, int y) { X = x; Y = y; }
// 方法
public double DistanceTo(Point other) => Math.Sqrt((X-other.X)*(X-other.X) + (Y-other.Y)*(Y-other.Y));
}
// 實例化:new 操作符分配內存、調用構造函數、返回引用
Point p1 = new Point(0, 0);
Point p2 = new Point(3, 4);
Console.WriteLine(p1.DistanceTo(p2)); // 5
// 內存自動回收:GC 管理,無需手動釋放 (無析構函數時)
| 成員類型 | 關鍵字/語法 | 用途 | 靜態/實例 |
|---|---|---|---|
| 常數 | const | 編譯時常量,隱式 static | Static |
| 字段 | field | 狀態存儲 | Static / Instance |
| 方法 | method | 行為邏輯 | Static / Instance |
| 屬性 | property (get/set) | 封裝字段讀寫,可含邏輯 | Static / Instance |
| 索引器 | this[params] | 類似數組訪問 | Instance |
| 事件 | event | 發布-訂閱通知 | Static / Instance |
| 運算符 | operator | 重載運算符 (+, ==, implicit 等) | Static |
| 構造函數 | ctor | 實例/類初始化 | Instance / Static |
| 析構函數 | ~ClassName() | 非托管資源清理 | Instance |
| 嵌套類型 | class/struct/enum | 邏輯分組、封裝 | - |
| 修飾符 | 訪問範圍 | 適用成員 |
|---|---|---|
public | 無限制 | 所有 |
protected | 包含類 + 派生類 | 類成員 |
internal | 當前程序集 | 所有 |
protected internal | 當前程序集 OR 派生類 | 類成員 |
private | 僅包含類 | 類成員 |
private protected | 當前程序集 AND 派生類 (C# 7.2+) | 類成員 |
默認可訪問性:類默認 internal,成員默認 private。
// 基類
public class Shape {
public virtual double Area() => 0; // 虛方法,可重寫
public virtual void Draw() => Console.WriteLine("Drawing shape");
}
// 派生類
public class Circle : Shape {
public double Radius { get; set; }
public Circle(double r) => Radius = r;
public override double Area() => Math.PI * Radius * Radius; // 重寫
public override void Draw() => Console.WriteLine($"Drawing circle R={Radius}");
}
// 抽象類:不可實例化,含抽象成員強制派生類實現
public abstract class Animal {
public abstract void MakeSound(); // 抽象方法,無實現
public void Breathe() => Console.WriteLine("Breathing"); // 普通方法
}
public class Dog : Animal {
public override void MakeSound() => Console.WriteLine("Woof!");
}
// 多態演示
Shape[] shapes = { new Circle(5), new Rectangle(3,4) };
foreach (var s in shapes) Console.WriteLine($"Area: {s.Area()}"); // 動態綁定調用派生類實現
// 隱式轉換:派生類 → 基類
Shape s = new Circle(2); // 合法
Circle c = (Circle)s; // 顯式轉換,運行時檢查
public class Color {
// 靜態字段:屬於類,全程序單一副本
public static readonly Color Red = new Color(255,0,0);
public static readonly Color Green = new Color(0,255,0);
public static readonly Color Blue = new Color(0,0,255);
// 實例字段:每個對象獨立副本
private byte _r, _g, _b;
// 構造函數初始化
public Color(byte r, byte g, byte b) { _r=r; _g=g; _b=b; }
// readonly:僅能在聲明或構造函數賦值
public readonly string Name;
public Color(byte r, byte g, byte b, string name) : this(r,g,b) => Name = name;
}
public void Demo(
int valueParam, // 值參數:傳遞副本,修改不影響原值
ref int refParam, // 引用參數:別名,修改影響原變量,調用需 ref
out int outParam, // 輸出參數:必須在方法內賦值,調用需 out
params int[] paramsArray // 參數數組:可變長度參數,僅最後一個
) {
outParam = 42; // out 必須賦值
}
// 調用
int a=1, b=2, c;
Demo(a, ref b, out c, 10, 20, 30);
// a 不變,b 可能變,c=42,paramsArray=[10,20,30]
public class Calculator {
public int Add(int a, int b) => a+b;
public double Add(double a, double b) => a+b;
public int Add(int a, int b, int c) => a+b+c;
// 簽名 = 方法名 + 參數列表(數量/類型/修飾符),與返回類型無關
}
virtual:基類提供默認實現,派生類可選重寫override:派生類重寫虛擬/抽象方法,**必須**簽名一致abstract:無實現,**強制**派生類重寫,僅允許在 abstract 類中sealed override:封鎖繼承鏈,子類不可再重寫
public class Person {
private string _name;
// 完全屬性
public string Name {
get => _name;
set {
if (string.IsNullOrWhiteSpace(value)) throw new ArgumentException("Name required");
_name = value.Trim();
}
}
// 自動實現屬性 (C# 3.0+),編譯器生成隱私字段
public int Age { get; set; }
// 僅讀屬性 (C# 6.0+)
public string Id { get; } = Guid.NewGuid().ToString("N");
// 初始化後不可變 (C# 9.0+ init)
public string Email { get; init; }
}
public class GradeBook {
private int[] _scores = new int[100];
public int this[int index] {
get => _scores[index];
set {
if (value < 0 || value > 100) throw new ArgumentOutOfRangeException();
_scores[index] = value;
}
}
}
// 使用
var gb = new GradeBook();
gb[0] = 95;
Console.WriteLine(gb[0]); // 95
public class Timer {
// 基於委托的事件
public event EventHandler Elapsed;
protected virtual void OnElapsed(ElapsedEventArgs e) => Elapsed?.Invoke(this, e);
public void Start() { /* ...觸發 OnElapsed... */ }
}
// 訂閱
var timer = new Timer();
timer.Elapsed += (sender, e) => Console.WriteLine($"Tick at {e.Time}");
timer.Start();
public struct Vector {
public double X, Y;
public static Vector operator +(Vector a, Vector b) => new Vector { X = a.X+b.X, Y = a.Y+b.Y };
public static Vector operator -(Vector a, Vector b) => new Vector { X = a.X-b.X, Y = a.Y-b.Y };
public static bool operator ==(Vector a, Vector b) => a.X==b.X && a.Y==b.Y;
public static bool operator !=(Vector a, Vector b) => !(a==b);
public override bool Equals(object obj) => obj is Vector v && this==v;
public override int GetHashCode() => HashCode.Combine(X, Y);
}
public class ResourceHolder : IDisposable {
private IntPtr _handle; // 非托管資源
// 實例構造函數
public ResourceHolder() => _handle = NativeAlloc();
// 靜態構造函數:類首次訪問前執行一次,無參數、無可訪問性
static ResourceHolder() { NativeInitLib(); }
// 析構函數 (Finalizer):GC 回收前調用,非確定性
~ResourceHolder() => Dispose(false);
// 標準 Dispose 模式
public void Dispose() { Dispose(true); GC.SuppressFinalize(this); }
protected virtual void Dispose(bool disposing) {
if (_handle != IntPtr.Zero) { NativeFree(_handle); _handle = IntPtr.Zero; }
}
}
private,暴露 public 屬性readonly、init、record (C# 9+) 減少可變狀態==/!=、/=、+/ - 成對(sender, e) 模式,支持弱引用防內存洩漏精通類與對象體系,是編寫健壯、可維護、高性能 C# 代碼的前提。從簡單的 DTO 到複雜的領域模型、框架基礎設施,皆建立在此核心之上。