承接上篇,本文進一步探討巢狀類型 (Nested Types) 的進階特性:內部類別如何存取外部私有成員、繼承規則、反射載入差異,並給出實務設計模式建議。
public class Outer
{
private string _secret = "private field";
private static void StaticMethod() => Console.WriteLine("Static");
internal void InternalMethod() => Console.WriteLine("Internal");
public void PublicMethod() => Console.WriteLine("Public");
public class Inner
{
public void AccessAll(Outer outer)
{
Console.WriteLine(outer._secret); // ✅ 私有欄位
Outer.StaticMethod(); // ✅ 私有靜態方法
outer.InternalMethod(); // ✅ internal 方法
outer.PublicMethod(); // ✅ public 方法
}
}
}
// 使用
var inner = new Outer.Inner();
inner.AccessAll(new Outer());
**規則**:巢狀類型視為外部類別的「一部分」,**完全忽略存取修飾詞** (private/protected/internal/public),可自由存取所有靜態/實例成員。這是語言規格保證,而非繼承關係。
public class Base
{
public class Nested
{
public virtual void Show() => Console.WriteLine("Base.Nested");
}
}
public class Derived : Base
{
public class Nested : Base.Nested // 明確繼承基底的巢狀類別
{
public override void Show() => Console.WriteLine("Derived.Nested");
}
}
// 使用
Base.Nested bn = new Base.Nested(); bn.Show(); // Base.Nested
Derived.Nested dn = new Derived.Nested(); dn.Show(); // Derived.Nested
Base.Nested upcast = new Derived.Nested(); upcast.Show(); // Derived.Nested (多態生效)
內部類別繼承**不自動發生**,必須在衍生外部類別中**顯式宣告**同名巢狀類別並指定基底類別。這避免了隱式繼承帶來的驚訝。
// 一般類別
Type t1 = Type.GetType("MyNamespace.OuterClass.InnerClass"); // ❌ 找不到
// 巢狀類別:組件限定名稱中以 '+' 分隔巢狀層級
Type t2 = Type.GetType("MyNamespace.OuterClass+InnerClass, MyAssembly"); // ✅
// Activator.CreateInstance 同理
object instance = Activator.CreateInstance("MyAssembly", "MyNamespace.OuterClass+InnerClass");
IL/中繼資料中,巢狀類型完整名稱使用 `+` 連接 (如 `OuterClass+InnerClass`),而非 `.`。反射 API 皆遵循此規則。
| 模式 | 適用場景 | 範例 |
|---|---|---|
| **私有實作細節封裝** | 演算法內部輔助類別、狀態機狀態類別 | `private sealed class Node { ... }` 在樹狀結構內部 |
| **建構者/工廠內部類別** | 流暢介面建構複雜物件 | `public class Builder { ... }` 內建於 `Person` |
| **事件引數/選項類別** | 僅在特定事件/方法內使用的資料包 | `public class Options { ... }` 內建於服務類別 |
| **避免濫用** | 若類別可能被外部獨立使用、繼承、序列化,應提升為獨立檔案 | — |
巢狀類型提供**語彙作用域層級的封裝**,內部類別享有外部所有成員的存取權,繼承需顯式宣告,反射需用 `+` 號。善用於**實作細節隱藏、建構者模式、領域特定輔助類別**,可提高內聚、降低命名空間汙染。但切記:**可重用性優先時,提升為獨立類別**。