深入理解C中的类

12333社保查询网www.sz12333.net.cn 2026-02-12来源:人力资源和社会保障局

  本文对 C# 类的系统化、深度且易理解的讲解,覆盖类的所有核心组成部分(成员、修饰符、静态 / 实例特性、构造析构、关键字等)。以 “概念定义 + 核心特性 + 代码示例 + 使用场景” 的结构,帮你构建完整的类知识体系,同时点明新手易混淆的关键点。

一、类的本质与核心定位

  C# 是纯面向对象语言,类(Class) 是面向对象编程(OOP)的核心载体 —— 它是对 “数据(状态)” 和 “行为(操作)” 的封装,是创建对象(实例)的 “模板”。

  

  1

  2

  3

  4

  5

  6

  7

  8

  9

  10

  11

  // 最基础的类结构:包含数据(字段)和行为(方法)class Phone{ // 数据:描述手机的状态(字段) string _brand; int _batteryLevel; // 行为:手机能执行的操作(方法) void Call(string number) { } void Charge() { }}

二、类的成员:完整分类与说明

  类的成员是类的 “组成部分”,覆盖你提到的所有类型,按功能可分为以下大类,每类都有明确的职责:

  表格

  成员类型

  核心作用

  典型示例

  字段(Field)

  存储类 / 对象的原始数据(底层存储)

  private string _name;

  方法(Method)

  定义类 / 对象的行为(可执行逻辑)

  public void Run() { }

  属性(Property)

  封装字段的访问(可控的读 / 写)

  public string Name { get; set; }

  构造函数

  初始化类(静态构造)或对象(实例构造)

  public Phone() { }

  析构函数

  释放对象占用的非托管资源

  ~Phone() { }

  常量(Constant)

  定义编译期固定、不可变的值

  public const int MaxBattery = 100;

  索引器

  让对象支持 “数组式下标访问”

  public string this[int index] { get; }

  静态成员

  属于类本身(所有实例共享)

  public static int TotalPhones;

  其他成员

  事件、运算符重载、嵌套类等(进阶)

  public event Action OnLowBattery;

关键补充:成员修饰符的规范顺序

  C# 编译器不强制修饰符顺序,但遵循行业规范能提升代码可读性,推荐顺序(从左到右):

  访问修饰符 → 静态/实例 → 其他修饰符 → 类型/返回值 → 成员名

   正确示例:

  

  1

  2

  3

  4

  5

  // 访问修饰符(public) → 静态(static) → 只读(readonly) → 类型(int) → 成员名(DefaultPort)public static readonly int DefaultPort = 8080; // 访问修饰符(private) → 实例(默认) → 类型(string) → 成员名(_ip)private string _ip;

   不推荐(顺序混乱):

  

  1

  2

  static public int Timeout = 30; // 静态修饰符在访问修饰符前private readonly static string Url = "https://example.com"; // 只读在静态前

三、实例成员 vs 静态成员:核心差异

  这是类成员最核心的分类维度,新手最易混淆,需重点理解:

1. 实例类成员(非静态)
  • 归属:属于对象(实例) ,每个实例有独立的副本。
  • 访问条件:必须先通过new创建实例,才能访问。
  • 访问范围:实例成员可访问其他实例成员,也可访问静态成员。

      

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      25

      26

      class Employee{ // 实例字段:每个员工有自己的姓名和工号 public string Name; public int Id; // 实例方法:访问实例字段和静态字段 public void ShowInfo() { Console.WriteLine(#34;姓名:{Name},工号:{Id},部门:{Department}"); } // 静态字段:所有员工共享的部门信息 public static string Department = "研发部";}// 使用实例成员Employee emp1 = new Employee();emp1.Name = "张三";emp1.Id = 1001;emp1.ShowInfo(); // 输出:姓名:张三,工号:1001,部门:研发部Employee emp2 = new Employee();emp2.Name = "李四";emp2.Id = 1002;emp2.ShowInfo(); // 输出:姓名:李四,工号:1002,部门:研发部

    2. 静态字段
  • 归属:属于类本身,所有实例共享同一个值,内存中仅一份副本。
  • 初始化时机:类加载时初始化(早于实例创建)。
  • 核心特性:修改静态字段会影响所有实例。

      

      1

      2

      3

      4

      // 延续上面的Employee类Employee.Department = "产品部"; // 修改静态字段emp1.ShowInfo(); // 输出:姓名:张三,工号:1001,部门:产品部(emp1的部门也变了)emp2.ShowInfo(); // 输出:姓名:李四,工号:1002,部门:产品部(emp2的部门也变了)

    3. 从类的外部访问静态成员
  • 推荐方式:类名.静态成员(语义清晰,明确是类级成员)。
  • 不推荐方式:实例名.静态成员(编译器允许,但易误导,看起来像实例成员)。

      

      1

      2

      3

      4

      5

      6

      // 推荐:类名访问静态成员Console.WriteLine(Employee.Department); // 不推荐:实例名访问静态成员(编译器会警告)Employee emp = new Employee();Console.WriteLine(emp.Department); // 本质还是访问Employee.Department

    4. 静态函数成员(静态方法)
  • 归属:属于类本身,无实例上下文。
  • 核心限制:静态方法不能访问实例成员(因为没有this指向具体实例),但可访问静态成员。
  • 典型场景:工具类(如数学计算、数据转换)、全局逻辑。

      

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      static class MathTool // 静态类:只能包含静态成员,不能实例化{ // 静态字段 public static readonly double PI = 3.1415926; // 静态方法:计算圆面积(仅访问静态成员) public static double CalculateCircleArea(double radius) { return PI * radius * radius; } // 错误:静态方法不能访问实例成员(静态类中也无法定义实例成员) // public string Version = "1.0";}// 使用静态方法(无需new)double area = MathTool.CalculateCircleArea(5);Console.WriteLine(area); // 输出:78.539815

    5. 其他静态类成员类型

      除了静态字段 / 方法,还有这些常用静态成员:

      表格

      静态成员类型

      示例代码

      核心用途

      静态属性

      public static string AppName { get; set; }

      封装静态字段的访问

      静态构造函数

      static MathTool() { PI = 3.14; }

      初始化静态成员(仅执行一次)

      静态常量

      public const int MaxValue = 100;

      编译期固定值(无需加 static)

    四、成员常量 vs 静态量:深度对比

      新手极易混淆const(常量)、static(静态字段)、static readonly(静态只读字段),以下是精准区分:

    1. 成员常量(const)
  • 本质:编译期确定值,隐式静态(无需加static,加了会报错)。
  • 限制:仅支持基本类型(int、string、double 等),必须声明时赋值,不可修改。
  • 存储:值直接嵌入 IL 代码,而非存储在类的静态区域。

      

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      class Config{ // 正确:常量声明 public const int Timeout = 30; // 错误:const不能加static // public static const string Url = "https://example.com"; // 错误:const不能后期赋值 // public const double PI; // static Config() { PI = 3.14; }}

    2. 常量 vs 静态量 vs 静态只读量(核心对比)

      表格

      特性

      const(常量)

      static(静态字段)

      static readonly(静态只读)

      赋值时机

      编译期

      运行期(声明 / 静态构造)

      运行期(声明 / 静态构造)

      可修改性

      完全不可改

      可改(除非 readonly)

      仅静态构造中可改

      支持类型

      仅限基本类型

      任意类型

      任意类型

      内存存储

      嵌入 IL 代码

      类静态存储区

      类静态存储区

      适用场景

      固定不变的基础值

      需动态修改的全局值

      运行期初始化的全局只读值

      

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      class Example{ // 常量:编译期固定 public const int MaxRetry = 3; // 静态字段:可动态修改 public static string AppVersion = "1.0.0"; // 静态只读:运行期初始化,不可修改 public static readonly DateTime AppStartDate; // 静态构造函数:初始化静态只读字段 static Example() { AppStartDate = DateTime.Now; // 运行期赋值 }}// 测试Example.AppVersion = "1.0.1"; // 静态字段可改// Example.AppStartDate = DateTime.Now; // 报错:只读字段不能赋值// Example.MaxRetry = 5; // 报错:常量不能赋值

    五、属性(Property):字段的 “安全封装”

      属性是对字段的封装,解决了 “字段直接暴露导致数据不可控” 的问题,分为三类:

    1. 自动属性(简化版)

      编译器自动生成私有字段(幕后字段),无需手动定义,适合简单场景。

      

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      class User{ // 自动属性:读+写 public string Username { get; set; } // 自动只读属性:仅能通过构造函数赋值 public string UserId { get; } // 自动属性:只读(私有写) public int Age { get; private set; } // 构造函数初始化只读属性 public User(string userId) { UserId = userId; Age = 18; // 私有写可在类内部赋值 }}

    2. 手动属性(自定义逻辑)

      自定义get/set逻辑,支持数据验证、日志记录等,是属性的核心用法。

      

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      25

      26

      27

      28

      class Product{ // 私有字段:底层存储 private decimal _price; // 手动属性:封装_price,添加验证逻辑 public decimal Price { get { Console.WriteLine("读取价格"); return _price; } set { if (value < 0) throw new ArgumentException("价格不能为负数"); Console.WriteLine("设置价格:" + value); _price = value; } }}// 使用属性Product p = new Product();p.Price = 99.9m; // 调用set,输出:设置价格:99.9Console.WriteLine(p.Price); // 调用get,输出:读取价格 → 99.9// p.Price = -10; // 抛出异常:价格不能为负数

    3. 属性的核心优势
  • 数据校验:防止非法值赋值(如价格为负)。
  • 封装性:隐藏字段的存储细节,仅暴露可控的访问接口。
  • 扩展性:后续可在get/set中添加日志、通知等逻辑,不影响外部调用。六、构造函数:初始化的核心

      构造函数是类中用于初始化对象 / 类的特殊方法,分为实例构造函数和静态构造函数,两者差异是核心考点:

    1. 实例构造函数
  • 语法:与类名同名,无返回值,可加访问修饰符(public/private 等)。
  • 执行时机:每次new创建实例时执行(创建几个实例,执行几次)。
  • 重载:支持多个构造函数(参数不同),可通过this()调用其他构造函数。

      

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      25

      26

      27

      28

      29

      30

      31

      32

      33

      34

      35

      class Car{ public string Brand; public int Year; // 无参构造函数 public Car() { Brand = "未知"; Year = DateTime.Now.Year; Console.WriteLine("无参构造执行"); } // 有参构造函数(重载) public Car(string brand) : this() // 调用无参构造 { Brand = brand; Console.WriteLine("有参构造执行"); } // 多参数构造函数(重载) public Car(string brand, int year) : this(brand) // 调用单参数构造 { Year = year; Console.WriteLine("多参数构造执行"); }}// 测试:构造函数链式调用Car c = new Car("宝马", 2024);/* 输出顺序:无参构造执行有参构造执行多参数构造执行*/

    2. 静态构造函数
  • 语法:static 类名(),无参数、无访问修饰符、不可重载。
  • 执行时机:第一次访问类的静态成员 / 创建实例时,仅执行一次(CLR 自动调用,无法手动触发)。
  • 核心用途:初始化静态成员(如加载配置、注册服务)。

      

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      class LogManager{ // 静态字段 public static string LogPath; // 静态构造函数(仅执行一次) static LogManager() { // 初始化静态字段(模拟从配置读取) LogPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "log.txt"); Console.WriteLine("静态构造函数执行:初始化日志路径"); } // 静态方法 public static void WriteLog(string message) { File.AppendAllText(LogPath, #34;{DateTime.Now}: {message}\n"); }}// 第一次调用静态方法,触发静态构造函数LogManager.WriteLog("程序启动");// 第二次调用,静态构造函数不再执行LogManager.WriteLog("操作完成");

    3. 对象初始化语句

      简化对象创建,无需定义多个构造函数,直接为属性 / 字段赋值:

      

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      class Book{ public string Title { get; set; } public string Author { get; set; } public int Pages { get; set; }} // 对象初始化语句(无需构造函数)Book book = new Book{ Title = "C#实战", Author = "李四", Pages = 450};

    七、析构函数:对象的 “清理者”
  • 语法:~类名(),无参数、无访问修饰符、不可重载。
  • 执行时机:GC(垃圾回收器)回收对象时执行,不可手动调用,执行时机不可预测。
  • 核心用途:释放非托管资源(如文件句柄、数据库连接、网络套接字)。

      

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      class FileReader{ // 非托管资源:文件流 private FileStream _stream; public FileReader(string path) { _stream = new FileStream(path, FileMode.Open); } // 析构函数:释放非托管资源 ~FileReader() { // 安全释放资源(null判断) _stream.Close(); _stream.Dispose(); Console.WriteLine("析构函数执行:文件流已释放"); }}// 测试(析构函数由GC自动调用)FileReader reader = new FileReader("test.txt");reader = null; // 置为null,让GC回收GC.Collect(); // 手动触发GC(仅测试用,实际不推荐)

      注意:C# 中推荐使用IDisposable接口替代析构函数,可手动控制资源释放,更灵活。

    八、readonly 修饰符:运行期只读
  • 核心特性:readonly字段仅能在声明时或构造函数中赋值,后续不可修改。
  • 分类:
  • 实例 readonly:在实例构造函数中赋值,每个实例有独立值。
  • 静态 readonly:在静态构造函数中赋值,类级全局值。

      

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      25

      26

      27

      class Order{ // 实例readonly:每个订单的ID唯一 public readonly string OrderId; // 静态readonly:所有订单的默认币种 public static readonly string DefaultCurrency; // 实例构造函数:赋值实例readonly public Order() { OrderId = Guid.NewGuid().ToString(); // 运行期生成唯一ID } // 静态构造函数:赋值静态readonly static Order() { DefaultCurrency = "CNY"; // 运行期初始化 }}Order order1 = new Order();Order order2 = new Order();Console.WriteLine(order1.OrderId); // 唯一IDConsole.WriteLine(order2.OrderId); // 另一唯一ID// order1.OrderId = "123"; // 报错:readonly字段不能赋值// Order.DefaultCurrency = "USD"; // 报错:静态readonly字段不能赋值

    九、this 关键字:当前实例的 “代名词”

      this代表当前对象实例,主要有 4 个核心用途:

    1. 区分字段与参数(同名时)

      

      1

      2

      3

      4

      5

      6

      7

      8

      9

      class Person{ private string _name; public Person(string name) { this._name = name; // this._name是字段,name是参数 }}

    2. 调用同类的其他构造函数

      

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      class Person{ public string Name { get; set; } public int Age { get; set; } public Person() : this("未知", 18) // 调用双参数构造 { } public Person(string name, int age) { this.Name = name; this.Age = age; }}

    3. 作为参数传递给其他方法

      

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      class Person{ public void PrintInfo() { ShowDetails(this); // 将当前实例传递给方法 } private void ShowDetails(Person p) { Console.WriteLine(#34;姓名:{p.Name},年龄:{p.Age}"); }}

    4. 在索引器中使用(代表当前对象)

      

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      class Collection{ private string[] _items = new string[10]; // 索引器:this代表当前对象 public string this[int index] { get { return _items[index]; } set { _items[index] = value; } }}

    十、索引器:对象的 “数组式访问”

      索引器允许对象像数组一样通过[下标]访问成员,核心语法:

      public 类型 this[参数列表] { get; set; }

    1. 基础索引器(int 下标)

      

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      25

      26

      27

      28

      29

      30

      31

      32

      class StudentList{ private List _students = new List(); // 索引器:int下标访问学生姓名 public string this[int index] { get { if (index < 0 || index >= _students.Count) throw new IndexOutOfRangeException("索引超出范围"); return _students[index]; } set { if (index < 0 || index >= _students.Count) _students.Add(value); else _students[index] = value; } } // 获取学生数量 public int Count => _students.Count;}// 使用索引器StudentList list = new StudentList();list[0] = "张三"; // 调用set(添加)list[1] = "李四"; // 调用set(添加)Console.WriteLine(list[0]); // 调用get → 张三Console.WriteLine(list.Count); // 输出:2

    2. 重载索引器(多类型下标)

      

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      class StudentList{ // 重载索引器:string下标(根据姓名查索引) public int this[string name] { get { return _students.IndexOf(name); } }} // 使用重载索引器Console.WriteLine(list["李四"]); // 输出:1

    总结(核心关键点)
    1. 1. 类的成员核心分类:按 “归属” 分为实例成员(属于对象,每次 new 都初始化)和静态成员(属于类,仅初始化一次);按 “功能” 分为字段、方法、属性、构造函数等。
    2. 2. 易混淆概念区分:
    3. const是编译期常量(不可改、仅基本类型),static readonly是运行期只读常量(可任意类型);
    4. 实例构造函数初始化对象(每次 new 执行),静态构造函数初始化类(仅执行一次)。
    5. 3. 核心语法糖 / 关键字:
    6. 属性封装字段,实现可控访问;
    7. this代表当前实例,索引器让对象支持数组式访问;
    8. readonly限制字段仅构造函数赋值,保证数据不可篡改。

      掌握这些核心知识点,你就能彻底理解 C# 类的设计逻辑和使用方式,后续学习继承、多态、接口等进阶内容也会更轻松。

    本文标题:深入理解C中的类本文网址:https://www.sz12333.net.cn/zhzx/kexue/57468.html 编辑:12333社保查询网
  • 本站是社保查询公益性网站链接,数据来自各地人力资源和社会保障局,具体内容以官网为准。
    定期更新查询链接数据 苏ICP备17010502号-11