七、常量与字段(Constants and Fields)
CLR
第七章:常量与字段(Constants and Fields
1. 常量(Constants)
特点
- 编译时确定:值在编译期确定,不能修改。
- 隐式
static:常量自动是static,无需显式声明static。 - 存储方式:值被直接嵌入到使用它的代码中,而不是在运行时读取。
示例
public sealed class SomeLibraryType {
public const int MaxEntries = 50; // ✅ 编译期常量
}
IL 代码
IL_0006: ldc.i4.s 50 // 常量值直接嵌入
⚠️ 版本问题
如果引用常量的程序集不重新编译,更新 MaxEntries = 1000 不会影响旧的程序。
✅ 解决方案:使用 static readonly 代替 const(见下方)。
2. 只读字段(Readonly Fields)
特点
- 运行时确定:可以在 构造函数中初始化(可利用反射来修改)。
- 可以是任何类型(
const只能是基本类型)。 - 存储方式:值存储在内存中,而不是直接嵌入代码。
⚠️当某个字段是引用类型,并且该字段标记为readonly时,不可改变的是引用,而非字段引用的对象!
示例
public sealed class SomeLibraryType {
public static readonly int MaxEntries = 50; // ✅ 运行时常量
}
优点
- 可跨程序集更新:更改
MaxEntries = 1000,无需重新编译依赖程序集。 - 可存储复杂对象,如
DateTime.Now。
3. 字段(Fields)
字段的 4 种类型
| 修饰符 | 特点 | 示例 |
|---|---|---|
static |
静态字段,属于类,而非实例 | public static int Count; |
readonly |
只读字段,只能在构造函数初始化 | public readonly int ID; |
volatile |
防止编译器优化,用于多线程 | public volatile int status; |
| 普通字段 | 每个实例独立的存储 | public int age; |
✅ 示例
public class Example {
public static int StaticField; // 所有对象共享
public readonly int ReadonlyField; // 仅构造函数赋值
public volatile int VolatileField; // 线程安全
}
4. readonly vs const vs static readonly
| 特性 | const | readonly | static readonly |
|---|---|---|---|
| 赋值时机 | 编译时 | 运行时(构造函数) | 运行时(静态构造函数) |
是否 static |
隐式 static |
实例字段 | 静态字段 |
| 是否可变 | 不可变 | 构造后不可变 | 构造后不可变 |
| 适用场景 | 编译期常量 | 构造时确定的值 | 全局常量 |
5. Mermaid 图示
graph TD
A["const"] -->|编译时确定| B["直接嵌入代码"]
C["readonly"] -->|运行时确定| D["只能在构造函数中赋值"]
E["static readonly"] -->|静态构造时赋值| F["跨程序集可修改"]
6. 面试题 & 解析
1️⃣ const 和 readonly 的区别?
✅ 解析
const在编译期确定,不能更改。readonly在运行时确定,可在构造函数中赋值。- 推荐
readonly代替const以避免版本问题。
2️⃣ readonly 和 static readonly 的区别?
✅ 解析
readonly属于实例,每个对象可以有不同的值。static readonly属于类,所有对象共享同一值。
🔹 示例
public class Example {
public readonly int InstanceID; // 每个对象不同
public static readonly int GlobalID = 100; // 所有对象相同
}
3️⃣ volatile 关键字的作用?
✅ 解析
- 防止编译器优化,保证不同线程访问变量时数据一致性。
- 适用于 多线程共享的变量,如
bool isRunning;。
🔹 示例
public class Worker {
private volatile bool _running = true;
public void Stop() {
_running = false; // ✅ 确保线程读取到最新值
}
}
4️⃣ const 是否支持复杂对象?
✅ 解析
const仅支持基本类型 (int,string等)。- 复杂对象(如
DateTime)必须用static readonly。
🔹 示例
public class Constants {
public const int Number = 10; // ✅ 允许
public static readonly DateTime StartTime = DateTime.Now; // ✅ 允许
// public const DateTime Invalid = DateTime.Now; // ❌ 错误
}
5️⃣ const 是否可以在运行时修改?
✅ 解析
const不能在运行时修改,只能在编译期赋值。- 如需运行时修改,请使用
readonly或static readonly。
7. 总结
| 概念 | 核心考点 |
|---|---|
常量 (const) |
编译时确定,值直接嵌入代码 |
只读字段 (readonly) |
运行时确定,可在构造函数赋值 |
静态只读 (static readonly) |
跨程序集可修改,存储在类级别 |
volatile 关键字 |
防止线程优化,保证多线程可见性 |
推荐使用 readonly 代替 const |
避免跨程序集更新问题 |
点赞鼓励下,(づ ̄3 ̄)づ╭❤~
作者:世纪末的魔术师
出处:https://www.cnblogs.com/Firepad-magic/
Unity最受欢迎插件推荐:点击查看
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

浙公网安备 33010602011771号