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

目录

[一、内部类(Inner Class)](#一、内部类(Inner Class))

[1. ​什么是内部类?](#1. 什么是内部类?)

[2. ​内部类的作用](#2. 内部类的作用)

[3. ​如何定义内部类?](#3. 如何定义内部类?)

[4. ​常见应用场景](#4. 常见应用场景)

[二、分部类(Partial Class)](#二、分部类(Partial Class))

[1. ​什么是分部类?](#1. 什么是分部类?)

[2. ​分部类的写法](#2. 分部类的写法)

[3. ​分部方法(Partial Methods)​](#3. 分部方法(Partial Methods))

[三、内部类 vs 分部类](#三、内部类 vs 分部类)

四、总结与注意事项

[1. ​内部类的使用技巧](#1. 内部类的使用技巧)

[2. ​分部类的使用技巧](#2. 分部类的使用技巧)

[3. ​注意事项](#3. 注意事项)

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

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

2.密封类的作用

3.如何定义密封类?

4.常见应用场景

5.注意事项

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


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

一、内部类(Inner Class)

1. ​什么是内部类?

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

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

2. ​内部类的作用

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

3. ​如何定义内部类?

cpp 复制代码
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. ​分部类的写法

cs 复制代码
// 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 方法。
    • 若未实现,编译器会移除声明。
cs 复制代码
// 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 关键字修饰的类,表示禁止其他类继承它,是类继承链的终点。

cs 复制代码
public sealed class Logger 
{
    public void Log(string message) 
    {
        Console.WriteLine(message);
    }
}

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

2.密封类的作用

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

**3.**如何定义密封类?

使用关键字 sealed

cs 复制代码
public sealed class SecurityToken 
{
    private byte[] _encryptedData;

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

注意!!!!

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

4.常见应用场景

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

5.注意事项

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

6.​密封方法(扩展知识)​

在非密封类中,可用 sealed 关键字标记重写方法,禁止子类再次覆盖:

cs 复制代码
public class Device 
{
    public virtual void Initialize() { }
}

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

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

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

相关推荐
程序媛学姐13 分钟前
SpringRabbitMQ消息发送:RabbitTemplate与消息确认
java·开发语言·spring
Love__Tay15 分钟前
【学习笔记】Power BI 初级知识
笔记·学习·数据分析·powerbi
mxd0184816 分钟前
sojson。v5:新一代JavaScript代码保护工具的技术解析与应用场景
开发语言·javascript·ecmascript
浪淘沙jkp36 分钟前
大模型学习五:‌DeepSeek Janus-Pro-7B 多模态半精度本地部署指南:环境是腾讯cloudstudio高性能GPU 16G免费算力
学习·deepseek·janus-pro·janus-pro-7b
孞㐑¥37 分钟前
C++之红黑树
开发语言·c++·经验分享·笔记
字节旅行者1 小时前
C++中如何使用STL中的list定义一个双向链表,并且实现增、删、改、查操作
开发语言·数据结构·c++·链表
搞程序的心海1 小时前
用Scala玩转Flink:从零构建实时处理系统
开发语言·flink·scala
x66ccff1 小时前
[特殊字符] Pandas 常用操作对比:Python 运算符 vs Pandas 函数
开发语言·python·pandas
1111Alisa1 小时前
数据分析-Excel-学习笔记Day1
学习·数据分析·excel
逆风优雅2 小时前
python 爬取网站图片的小demo
开发语言·python