《Effective C#》读书笔记——条目19:保证0为值类型的有效状态<.NET资源管理>
2013-01-12 17:30
260 查看
.NET系统的默认初始化过程会将所有的对象设置为0。我们就会难免创建出一个初始化为0值的值类型,所以我们应该将0作为类型的默认值,可以避免一些不必要的Bug。
但是如果实例化一个Month,我们将会得到一个为0的默认值,而这并不是Month的合法值:
因此在创建自定义的枚举的时候,必须确保0是一个合法的有效选项,如果可能应该将最适合做默认值的选项表示0,如果没有合适的选项适合做默认值的话,可以把0表示未初始化的值(逻辑上),让类型的使用者知道它当前的状态,例如修改成下面这样:
在上面的程序中, 如果实例化一个LogMessage对象,msg字段为一个空引用,且不能直接对其进行初始化(private访问修饰符),不过我们可以通过使用属性类解决这个问题,通过属性将msg字段暴露给外界使用者。然后在属性中添加逻辑:在msg为null是返回一个空字符串:
这样做的好处就是将null引用的检查限制在一个单一的类型中,假如在程序集内部调用,那么Message属性很可能会被内联。这样既保证了代码的效率,也降低了错误发生的可能。
系统的初始化行为让所有的值类型的值都设置为0,这是我们无法避免的,我们能做的就是尽量将0设置为最可能的默认值,反正,也应该将0作为一个有效的合法选项,就行我们前面的第一个示例一样。
1.将0设置为枚举的有效值
使用枚举时我们必须将0设置为枚举的一个有效选项。所以枚举值都派生于System.ValueType。枚举默认的值开始于0,但是也可以自定义:public enum Month { //枚举的默认值是从0开始 Jan = 1, Feb = 2, Mar = 3, April = 4, May = 5, }
但是如果实例化一个Month,我们将会得到一个为0的默认值,而这并不是Month的合法值:
Month month = new Month(); Console.WriteLine((int)month); //输出0
因此在创建自定义的枚举的时候,必须确保0是一个合法的有效选项,如果可能应该将最适合做默认值的选项表示0,如果没有合适的选项适合做默认值的话,可以把0表示未初始化的值(逻辑上),让类型的使用者知道它当前的状态,例如修改成下面这样:
public enum Month { //枚举的默认值是从0开始 None = 0, Jan = 1, Feb = 2, Mar = 3, April = 4, May = 5, }
2.正确初始化包含引用的值类型
对于包含引用的值类型(如:字符串),也是比较在初始化的时候出现问题:public struct LogMessage { private int ErrLevel; private string msg; }
在上面的程序中, 如果实例化一个LogMessage对象,msg字段为一个空引用,且不能直接对其进行初始化(private访问修饰符),不过我们可以通过使用属性类解决这个问题,通过属性将msg字段暴露给外界使用者。然后在属性中添加逻辑:在msg为null是返回一个空字符串:
public struct LogMessage { private int ErrLevel; private string msg; public string LogMessage { get { return (msg! = null)?msg:string.Empty; } set { msg = value; } } }
这样做的好处就是将null引用的检查限制在一个单一的类型中,假如在程序集内部调用,那么Message属性很可能会被内联。这样既保证了代码的效率,也降低了错误发生的可能。
小节
系统的初始化行为让所有的值类型的值都设置为0,这是我们无法避免的,我们能做的就是尽量将0设置为最可能的默认值,反正,也应该将0作为一个有效的合法选项,就行我们前面的第一个示例一样。
相关文章推荐
- 《Effective C#》读书笔记——条目20:保证值类型的常量性和原子性<.NET资源管理>
- 《Effective C#》读书笔记——条目18:区分值类型和引用类型<.NET资源管理>
- 保证0为值类型的有效状态<.NET资源管理>
- 《Effective C#》读书笔记——条目27:让类型支持序列化<使用C#表达设计>
- 《Effective C#》读书笔记——条目14:尽量减少重复的初始化逻辑<.NET资源管理>
- 《Effective C#》读书笔记——条目17:实现标准的销毁模式<.NET资源管理>
- Effective C#阅读笔记-5对于值类型保证0是一个有效状态
- 《Effective C#》读书笔记——条目16:避免创建非必要的对象<.NET资源管理>
- 转:《Effective C#》读书笔记——条目17:实现标准的销毁模式<.NET资源管理>
- 《Effective C#》读书笔记——条目5:为类型提供ToString()方法<C#语言习惯>
- 《Effective C#》读书笔记——条目3:推荐使用is或as而不是强制转换类型<C#语言习惯>
- 《Effective C#》读书笔记——条目10:使用可选参数减少方法重载的数量<C#语言习惯>
- 《Effective C#》读书笔记——条目12:推荐使用成员初始化器而不是赋值语句<.NET资源管理>
- 《Effective C#》读书笔记——条目22:通过定义并实现接口替代继承<使用C#表达设计>
- 《Effective C#》读书笔记——条目23:理解接口方法和虚方法的区别<使用C#表达设计>
- 《Effective C#》读书笔记——条目25:用事件模式实现通知<使用C#表达设计>
- 《Effective C#》读书笔记——条目1:使用属性而不是可访问的数据成员<C#语言习惯>
- 《Effective C#》条款8:确保0为值类型的有效状态
- 《Effective C#》读书笔记——条目21:限制类型的可见性<使用C#表达设计>
- 《Effective C#》条款8:确保0为值类型的有效状态