首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 巢狀類型深度解析 (二):內部類別存取外部、繼承、反射與實務模式

     編輯:關於C語言

前言

承接上篇,本文進一步探討巢狀類型 (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),可自由存取所有靜態/實例成員。這是語言規格保證,而非繼承關係。

二、巢狀類型的繼承

1. 外部類別繼承時,內部類別可獨立繼承

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 { ... }` 內建於服務類別
**避免濫用**若類別可能被外部獨立使用、繼承、序列化,應提升為獨立檔案—

五、編譯器生成的命名慣例

  • 原始碼:`Outer.Inner`
  • IL/反射:`Outer+Inner`
  • 編譯器生成的顯式實作介面方法:`Outer+Inner.Method`
  • 匿名類別 (Lambda 閉包) :`Outer+<>c__DisplayClass0_0`

六、總結

巢狀類型提供**語彙作用域層級的封裝**,內部類別享有外部所有成員的存取權,繼承需顯式宣告,反射需用 `+` 號。善用於**實作細節隱藏、建構者模式、領域特定輔助類別**,可提高內聚、降低命名空間汙染。但切記:**可重用性優先時,提升為獨立類別**。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved