C# 常量与变量:写给小白的入门指南
一、变量:会变的盒子
变量就像我们日常生活中的盒子,可以存放不同的东西。在 C# 里,每个盒子都有自己的类型:
int age = 30; // 整数盒子
string name = "张三"; // 文字盒子
double height = 1.75; // 小数盒子
关键特性:
1.可以随时修改内容
age = 31; // 盒子里的数字变了
2.自动推断类型(用 var)
var today = DateTime.Now; // 自动知道是日期类型
内存小故事:
- 值类型(如整数):像放在口袋里,随用随取
- 引用类型(如字符串):像存在仓库,口袋里只存地址
二、常量:永远不变的标记
常量就像刻在石碑上的字,一旦写下就不能更改:
const double Pi = 3.14159; // 数学常数
const string Version = "v1.0"; // 版本号
使用场景:
- 固定不变的数据(如圆周率)
- 配置参数(如 API 密钥)
- 错误提示语(如 "网络连接失败")
与变量的区别:
const int MaxRetry = 3; // 石碑上的字
int currentRetry = 0; // 可以修改的计数器
三、只读字段:出生后不能变的属性
只读字段像出生证明上的信息,出生后就不能更改:
public class User {
public readonly string Id; // 身份证号
public User(string userId) {
Id = userId; // 只能在出生时(构造函数)填写
}
}
使用场景:
- 对象的唯一标识(如用户 ID)
- 初始化后不变的配置(如数据库连接字符串)
四、常见误区与避坑指南
误区 1:把动态数据当常量
// 错误示范
const string UserName = GetCurrentUser();
// 错误原因:常量必须在编译时确定值
误区 2:过度使用常量
// 错误示范
const string ErrorMessage = "文件未找到"; // 应该用静态只读字段
正确做法:
public static readonly string ErrorMessage = "文件未找到";
误区 3:忽略字符串驻留
// 重复创建相同字符串
string a = "Hello";
string b = "Hello"; // 其实它们指向同一块内存
五、性能优化小技巧
技巧 1:提取重复计算
// 重复计算
for (int i=0; i<1000; i++) {
result += i * Math.PI;
}
// 优化方案
const double Pi = Math.PI;
for (int i=0; i<1000; i++) {
result += i * Pi;
}
技巧 2:使用静态只读字段
public static class CountryCodes {
public static readonly Dictionary<string, string> Codes =
new Dictionary<string, string> {
{"CN", "中国"},
{"US", "美国"}
};
}
六、实战案例:配置管理系统
public class AppConfig {
// 编译时常量(固定不变)
public const string Environment = "生产环境";
public const int MaxConnections = 50;
// 运行时常量(初始化后不变)
public static readonly string[] AllowedOrigins = {
"https://api.example.com",
"https://www.example.com"
};
// 动态配置(可以修改)
public static string DatabaseConnection { get; private set; }
public static void LoadConfig() {
DatabaseConnection = "Server=localhost;Database=MyDB";
}
}
使用示例:
Console.WriteLine($"当前环境:{AppConfig.Environment}");
Console.WriteLine($"最大连接数:{AppConfig.MaxConnections}");
七、常见问题解答
Q:const 和 readonly 有什么区别?
- const:刻在石碑上(编译时确定)
- readonly:写在纸上(运行时确定,但只能写一次)
Q:为什么字符串是特殊的引用类型?
- 因为字符串内容不可变,相同内容的字符串会共享内存
Q:什么时候该用变量?什么时候该用常量?
- 经常变化的数据 → 变量
- 固定不变的数据 → 常量
- 初始化后不变的数据 → 只读字段
完整概念速查表
分类 | 概念 | 说明 |
---|---|---|
变量 | 值类型 | 存储在栈中(如 int, bool) |
引用类型 | 存储在堆中(如 string, class) | |
动态类型 | dynamic 关键字,运行时解析 | |
常量 | const | 编译时常量,必须初始化 |
static readonly | 运行时常量,初始化后不可变 | |
readonly 实例字段 | 构造函数中初始化 | |
内存管理 | 栈分配 | 局部变量,自动回收 |
堆分配 | 引用类型,需 GC 管理 | |
字符串驻留 | 相同内容字符串共享内存 |