C#核心学习(八)面向对象--封装(7)终章 C#内部类和分部类

发布于:2025-04-06 ⋅ 阅读:(25) ⋅ 点赞:(0)

目录

一、内部类(Inner Class)

1. ​什么是内部类?

2. ​内部类的作用

3. ​如何定义内部类?

4. ​常见应用场景

二、分部类(Partial Class)

1. ​什么是分部类?

2. ​分部类的写法

3. ​分部方法(Partial Methods)​

三、内部类 vs 分部类

四、总结与注意事项

1. ​内部类的使用技巧

2. ​分部类的使用技巧

3. ​注意事项

补充一个小知识:密封类:

1.​什么是密封类?        用 sealed 关键字修饰的类,表示禁止其他类继承它,是类继承链的终点。

2.密封类的作用 

3.如何定义密封类?

4.常见应用场景

5.注意事项

6.​密封方法(扩展知识)​        在非密封类中,可用 sealed 关键字标记重写方法,禁止子类再次覆盖:


          在C#开发中,你是否为代码臃肿、逻辑外泄或意外继承而头疼?内部类将关联逻辑嵌套封装,​分部类拆解巨型代码文件,​密封类则终结不受控的继承链——三者如同封装设计的“三叉戟”,分别解决代码组织、维护复杂度与安全性问题。本文将用真实案例解析它们的核心价值,助你写出更简洁、安全且易维护的代码。

一、内部类(Inner Class)

1. ​什么是内部类?

        内部类(嵌套类)是定义在另一个类或结构体内部的类。其主要目的是逻辑分组封装细节

  • 访问权限特点
    • 默认访问修饰符为 private,可显式指定为 public/protected/internal
    • 可访问外部类的私有成员(包括字段、方法)。

2. ​内部类的作用

  • 隐藏实现细节:将辅助类(如迭代器、状态机)隐藏在外部类内部。
  • 逻辑聚合:将与外部类紧密相关的类组织在一起。
  • 访问控制:限制内部类仅在外部类范围内使用。

3. ​如何定义内部类?

public class OuterClass 
{
    private string _secret = "Confidential";
    
    // 内部类
    private class InnerClass 
    {
        public void Print(OuterClass outer) 
        {
            // 访问外部类的私有字段
            Console.WriteLine(outer._secret);
        }
    }
    
    public void UseInnerClass() 
    {
        // 创建内部类实例
        InnerClass inner = new InnerClass();
        inner.Print(this);
    }
}

// 使用示例
OuterClass outer = new OuterClass();
outer.UseInnerClass(); // 输出 "Confidential"

4. ​常见应用场景

  • 迭代器模式:封装集合的遍历逻辑。
  • Builder模式:隐藏复杂对象的构造过程。
  • 状态管理:在有限状态机中定义状态类。

二、分部类(Partial Class)

1. ​什么是分部类?

        分部类(partial class)允许将一个类拆分到多个文件中定义,编译器会合并处理。

  • 核心用途
    • 分离自动生成代码与手动编写代码(如ASP.NET Web Forms、WinForms设计器文件)。
    • 大型类的模块化管理。

2. ​分部类的写法

// File1.cs
public partial class DataProcessor 
{
    public void LoadData() 
    {
        // 数据加载逻辑
    }
}

// File2.cs
public partial class DataProcessor 
{
    public void ProcessData() 
    {
        // 数据处理逻辑
    }
}

// 编译器合并后的等效代码:
public class DataProcessor 
{
    public void LoadData() { ... }
    public void ProcessData() { ... }
}

3. ​分部方法(Partial Methods)​

  • 定义在分部类中的方法,可分离声明与实现。
  • 规则
    • 必须为 partial void 方法。
    • 若未实现,编译器会移除声明。
// File1.cs
public partial class Logger 
{
    // 声明分部方法
    partial void LogStart();

    public void Start() 
    {
        LogStart(); // 若未实现,此行代码会被移除
    }
}

// File2.cs
public partial class Logger 
{
    // 实现分部方法
    partial void LogStart() 
    {
        Console.WriteLine("Logging started.");
    }
}

三、内部类 vs 分部类

特性 内部类(嵌套类)​ 分部类(Partial Class)​
核心目的 逻辑分组与封装细节 拆分代码到多个文件
文件组织 同一文件中定义 跨多个文件定义
访问权限 可访问外部类私有成员 同普通类(无特殊权限)
典型场景 迭代器、状态类 代码生成工具、大型类模块化管理

四、总结与注意事项

1. ​内部类的使用技巧

  • 访问控制:优先设为 private,仅在需要时开放访问。
  • 避免滥用:过度嵌套会导致代码可读性下降。
  • 应用场景:适合封装与外部类强相关的辅助逻辑。

2. ​分部类的使用技巧

  • 代码生成友好性:分离工具生成的代码(如Entity Framework实体类)。
  • 团队协作:多人协作时可按功能模块拆分文件。
  • 分部方法限制:仅支持 void 返回类型且不能为 public

3. ​注意事项

  • 内部类的序列化:嵌套类可能增加序列化复杂度。
  • 分部类的命名空间:所有分部类必须在同一命名空间。
  • 代码导航:分部类可能增加IDE中代码跳转的复杂度。

         结语:通过内部类隐藏复杂逻辑,利用分部类拆分代码文件,C#的封装特性让代码更加模块化、易维护。保持代码简洁,避免过度设计,是高效开发的关键!我目前还没有什么应用过的场景,目前来说我们不必了解太多,等到学到框架的时候,可以继续深入。

补充一个小知识:密封类:

        这个知识点,大家可以在后面看了继承以后再来观看会有更深的体会,因为在继承中,有的时候,会为了保护最底层不被继续继承后随意修改,所以使用关键字进行密封禁止其他的类继承。

1.​什么是密封类?
        用 sealed 关键字修饰的类,表示禁止其他类继承它,是类继承链的终点。

public sealed class Logger 
{
    public void Log(string message) 
    {
        Console.WriteLine(message);
    }
}

// 编译错误:无法继承密封类
public class FileLogger : Logger { } 

2.密封类的作用 

  • ​防止派生:保护核心类逻辑,避免被意外继承或篡改(如系统类 String 是密封的)。
  • ​性能优化:帮助编译器内联方法调用(减少虚方法表开销)。
  • ​框架设计:明确限制用户扩展点(如某些设计模式中的最终组件)。

3.如何定义密封类?

        使用关键字 sealed

public sealed class SecurityToken 
{
    private byte[] _encryptedData;

    public void Decrypt(string key) 
    {
        // 核心解密逻辑(禁止外部覆盖)
    }
}

注意!!!!

  • ​可继承其他类:密封类自身可以继承其他非密封类。
  • ​不可被继承:任何尝试继承的操作都会导致编译错误。

4.常见应用场景

  • 工具类:提供静态方法且无需扩展(如 Math 类)。
  • 敏感操作类:加密、授权等需要保护完整性的逻辑。
  • 性能关键代码:高频调用的基础类型(如游戏引擎中的向量计算类)。
  • 框架约束:明确禁止用户自定义子类(如ASP.NET中的某些管道组件)。

5.注意事项

  • 慎用密封:过度使用会限制代码扩展性,需权衡灵活性和安全性。
  • 配合静态类:若类完全无需实例化,可改用 static class(隐式密封)。
  • 单元测试:密封类可能增加Mock测试难度,可通过接口解耦。
  • 性能权衡:现代编译器优化能力较强,除非实测有收益,否则不必仅为性能而密封

6.​密封方法(扩展知识)​
        在非密封类中,可用 sealed 关键字标记重写方法,禁止子类再次覆盖:

public class Device 
{
    public virtual void Initialize() { }
}

public class Printer : Device 
{
    // 子类重写并密封该方法
    public sealed override void Initialize() 
    {
        // 打印机专用初始化
    }
}

public class LaserPrinter : Printer 
{
    // 编译错误:无法覆盖密封方法
    public override void Initialize() { } 
}

        结语:密封类作为继承链的"终结者",在保护核心逻辑和性能优化中扮演关键角色。结合框架设计与实际需求,合理使用能让代码更健壮、更高效!