平时做技术实践时,很多问题不是概念不会,而是细节没串起来。拿“C# 静态成员与非静态成员的实现方法”来说,它看着像小点,放到项目里常会牵出环境、配置、兼容性和维护成本。下面按实际采用顺序,把思路、关键写法和容易踩坑的地方讲清楚,便于大家直接对照操作。
一、核心概念(必背区分)
1. 非静态成员(实例成员)
无 static 修饰:字段、属性、方法
- 属于 对象(实例)
- 每个对象拥有独立一份数据,对象之间互不干扰
- 必须 new 对象后,借助对象名调用
2. 静态成员
有 static 修饰:静态字段、静态属性、静态方法
- 属于 类,不属于对象
- 全局唯一、所有对象共享同一份数据
- 直接借助 类名.成员 调用,无需 new 对象
二、调用语法规则(固定死规则)
1. 非静态成员调用
必须实例化对象 → 对象名.成员
People p1 = new People();
p1.F1();
p1.Id = 1;
2. 静态成员调用
直接类名调用 → 类名.成员
People.Age = 10;
People.F2();
三、静态与非静态 互相访问规则(超级高频考点)
1. 非静态方法 / 属性能够随意访问静态成员
非静态环境中,既能用非静态,也能用静态
public void F1()
{
// 允许访问静态属性、静态方法
Age = 10;
F2();
}
2. 静态方法 / 属性不能直接访问非静态成员
静态属于类,非静态属于对象,静态中没有当前对象
如果非要访问:必须手动 new 对象调用
public static void F2()
{
// 错误:直接调用非静态成员报错
// Id = 1;
// F1();
// 正确:手动 new 对象访问
People p = new People();
p.F1();
p.Id = 1;
}
总结一句话规则
- 非静态能够随便碰静态
- 静态不能直接碰非静态
四、静态与非静态 数据存储区别(内存原理)
1. 非静态属性(独立数据)
每个对象拥有自己独立的数据,互不影响
People p1 = new People();
p1.AddNum(); // p1.Num = 1
People p2 = new People();
p2.AddNum(); // p2.Num = 1
// 两个对象Num互不干扰,都是1
Console.WriteLine(p1.GetNum()); //1
Console.WriteLine(p2.GetNum()); //1
2. 静态属性(共享数据)
所有对象共享同一份静态数据,一改全改
如果 Num 是静态属性:
p1.AddNum(); //静态Num=1
p2.AddNum(); //静态Num=2
// 全部共享同一个值
Console.WriteLine(p1.GetNum()); //2
Console.WriteLine(p2.GetNum()); //2
五、超级易错坑点(笔试必坑)
1. 属性赋值死循环
禁止在属性set中给属性本身赋值
//错误写法:死循环
set
{
Id = value;
}
//正确写法:给字段赋值
set
{
id = value;
}
原因:Id=值 会再次触发set访问器,无限递归 → 栈溢出
2. 静态无this
静态方法中 不能采用this,因为this代表当前实例对象
3. 静态构造函数只执行一次
静态成员在程序生命周期内 只初始化一次,全局共享
六、静态 VS 非静态 终极对比表
对比项 | 非静态成员 | 静态成员 |
|---|---|---|
修饰符 | 无 static | 有 static |
归属 | 对象(实例) | 类 |
调用方式 | 对象名.成员 | 类名.成员 |
数据特点 | 每个对象独立数据 | 所有对象共享同一份数据 |
互相访问 | 可直接访问静态 | 不可直接访问非静态 |
this关键字 | 能够采用 | 不能够采用 |
七、满分背诵口诀
- static是静态,属于类,全局共享唯一数据
- 无static实例,属于对象,每个对象独立数据
- 非静可访静,静态不访非静
- 属性set只赋值给字段,千万别赋值给属性
- 静态类名点,非静对象点
理解这一步时,总的来说,C# 静态成员适合结合实际项目边做边理解。先抓住核心思路,再逐步补上细节和边界处理,最后效果会更稳定,也更容易复用。
