Effective C# Item8:确保0是值类型的有效状态
.NET会将对象的值默认设置为0,对于值类型来说,例如struct,我们无法阻止开发人员将结构体中的成员设置为0,因此,我们需要将0设置为有效状态。
对于枚举类型来说,如果通过new的方式新建一个枚举类型的对象,那么对象的值是0,代码如下。

1 public enum EnumSex
2 {
3 Female = 1,
4 Male = 2
5 }
6
7 private static void TestEnum()
8 {
9 EnumSex sex = new EnumSex();
10 Console.WriteLine(sex.ToString());
11 }
上述代码的运行结果是向控制台中输出0,但是EnumSex中并没有对0进行定义,因此,这时,sex对象的状态已经是一个非法状态了。
很多情况下,为了解决这个问题,我们都是这样来使用枚举
EnumSex sex = EnumSex.Male;
1 public struct Employee
2 {
3 private string m_strName;
4
5 public string Name
6 {
7 get { return m_strName; }
8 set { m_strName = value; }
9 }
10 private EnumSex m_sex;
11
12 public EnumSex Sex
13 {
14 get { return m_sex; }
15 set { m_sex = value; }
16 }
17 }
18
19 private static void TestStruct()
20 {
21 BirthInfo birthInfo = new BirthInfo();
22 Console.WriteLine(birthInfo.Birth);
23 Console.WriteLine(birthInfo.Birth.ToString());
24 }
以上面这种方式来做,是可以避免“0”问题,但是我们来查看以下代码。

1 public struct Employee
2 {
3 private string m_strName;
4
5 public string Name
6 {
7 get { return m_strName; }
8 set { m_strName = value; }
9 }
10 private EnumSex m_sex;
11
12 public EnumSex Sex
13 {
14 get { return m_sex; }
15 set { m_sex = value; }
16 }
17 }
18
19 private static void TestEmployee()
20 {
21 Employee emp= new Employee();
22 Console.WriteLine(emp.Sex);
23 }
上述代码的执行结果是向控制台中输出0,因为当我们通过new的方式新建一个Employee类型的对象时,会初始化Sex,Sex在初始化后的值就是0。
我们再来看下面的代码。
1 private static void TestEmployee()
2 {
3 Employee emp= new Employee();
4 Console.WriteLine(emp.Name);
5 Console.WriteLine(emp.Name.ToString());
6 }
上述代码在执行过程中,是会抛出空指针异常的,究其原因,当我们在通过new的方式新建一个Employee类型的对象时,会初始化Name属性,如果程序没有对其进行设置,默认的初始值是空,这时直接调用Name属性是没有问题的,但是调用Name属性的方法(这里是ToString()方法),就会抛出空指针异常。
因此,我们在程序中,首先应该对“0”的情况进行处理,以保证“0”是一个合法的状态;其次,我们应该考虑如何在默认构造函数或者属性的get方法中对成员变量赋默认值,以避免出现空指针异常的情况。
作者:李潘
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通