LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

深入理解C#中的类Class

admin
2026年2月9日 12:2 本文热度 137

本文对 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($"姓名:{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.9
Console.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, $"{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); // 唯一ID
Console.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($"姓名:{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<string> _students = new List<string>();

    // 索引器: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. 易混淆概念区分
    • • const是编译期常量(不可改、仅基本类型),static readonly是运行期只读常量(可任意类型);
    • • 实例构造函数初始化对象(每次 new 执行),静态构造函数初始化类(仅执行一次)。
  3. 3. 核心语法糖 / 关键字
    • • 属性封装字段,实现可控访问;
    • • this代表当前实例,索引器让对象支持数组式访问;
    • • readonly限制字段仅构造函数赋值,保证数据不可篡改。

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


该文章在 2026/2/9 12:02:58 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2026 ClickSun All Rights Reserved