《Effective C#》Item 8:确保“0”在值类型中是有效的
来源:互联网 发布:手机视频水印软件 编辑:程序博客网 时间:2024/05/22 04:05
大家在看了这标题后,肯定会觉的,为什么要确保“0”是有效的,这一点主要是跟值类型的内存分配有关,值类型有默认的构造函数,这是没法避免的,因此值类型变量中的成员在初始化的时候所出现的细微问题(对于值类型这方面的知识可以参看我前面一篇文章)。
http://blog.csdn.net/Knight94/archive/2006/07/01/861383.aspx
日常中比较常见的两种值类型,一个是enum定义的枚举类型,一个是用struct定义的数据类型。那我接下来就分别说明这两种类型如果不定义“0”为一个有效值的所能造成的后果,再分别说明如何加以修改来弥补这类错误。
对于enum定义的枚举类型来说,默认的起始值为0,但是如果在定义的时候,按照如下的方式去定义的话,有时候会造成意想不到的错误。
public enum ERROR_CODE
{
INVALID_FILE_NAME = 1001,
CANT_BE_ACCESS = 1002,
}
如上的定义是没有默认值0的,那么当我显示的去定义一个此类型变量,例如:
ERROR_CODE myError = new ERROR_CODE();
Debug.WriteLine( string.Format( "{0}", (int)myError ) );
可以看出如上的输出结果是0,但是它不是一个有效的值,也许这种错误可能很少出现,但是在struct复合类型中这种错误表现得更为明显。例如:
public struct ErrorMsg
{
private ERROR_CODE err;
private string strMsg;
// other properties or methods here
}
对于如上的结构类型来说,由于默认构造函数存在,所以当创建一个ErrorMsg变量的时候,那么对于err这个成员的值是无效的。有人可能会说,增加构造函数来限制等等的做法来避免这类错误。那么为什么与其在ErrorMsg中增加限制,不如在定义ERROR_CODE的时候就避免呢。其实这类错误的避免方法很简单,只要在ERROR_CODE中增加0的有效定义即可,例如比较正确形式的应该如下:
public enum ERROR_CODE
{
NO_ERROR = 0,
INVALID_FILE_NAME = 1001,
CANT_BE_ACCESS = 1002,
}
按照如上的做法就可以避免定义ERROR_CODE变量或者被组合到别的类型中的时候,都不会发生初始值是无效的尴尬局面。
在这本书中,对于枚举类型还提到一点,就是增加Flags标记的时候,一定要以None作为0,例如:
[Flags]
public enum Style
{
None = 0,
Flat = 1,
}
这样的目的是为了在与和或操作的时候能有意义。这方面的例子我就不多说了,例如:某个connection的状态,或者文件的某种属性等等都会用到类似的做法。
除了枚举类型外,对于struct定义的值类型来说,如果struct类型所包含的成员类型都是值类型的话,是没有什么问题(如果是自定义枚举类型,要参照上面所说的方法进行处理);但是如果包含引用类型,则需要进行初始化,避免在访问的时候出现异常。例如对于前面所说的ErrorMsg来说,由于struct默认构造函数的存在,有可能在ErrorMsg类型变量在构造后,其的strMsg成员不是有效的。除了string类型外,常见的还有数组类型。如何避免类似的问题呢,方法是采用属性来实现。例如:
public struct ErrorMsg
{
private ERROR_CODE err;
private string strMsg;
public string Message
{
get
{
if( strMsg == null ) return string.Empty;
else
return strMsg;
}
}
// other properties or methods here
}
public struct IntArray
{
private int[] nArray;
public int[] Array
{
get
{
if( nArray == null )
nArray = new int[10];
return nArray;
}
}
}
所以在论坛上经常看到有人提出不能在struct中定义一个固定维数的数组,那么参照如上的方法,这类问题就能得到很好地解决。
最后再提一句,对于要确保“0”在所定义的值类型中是有效的这一点来说别小看。屏蔽错误从细微做起,而且好的编码习惯会使后面的工作事半功倍。
- 《Effective C#》Item 8:确保“0”在值类型中是有效的
- 转:《Effective C#》Item 8:确保“0”在值类型中是有效的
- 《Effective C#》Item 8:确保“0”在值类型中是有效的
- Effective C# 原则8:确保0对于值类型数据是有效的
- 《Effective C#》条款8:确保0为值类型的有效状态
- Effective C# Item8:确保0是值类型的有效状态
- 条款8:确保0为值类型的有效状态
- 确保0为值类型的有效状态
- Item 32:确保public继承是"is a"的关系 Effective C++笔记
- 改善C#程序的50种方法 条款8:确保0为值类型的有效状态
- 提高C#编程水平的50个要点 之八“在值类型中,确保0是一个合法的数据”
- 《Effective C#》Item 6:区分值类型和引用类型
- 《Effective C#》Item 6:区分值类型和引用类型
- Effective C#阅读笔记-5对于值类型保证0是一个有效状态
- [翻译] Effective C++, 3rd Edition, Item 4: 确保 objects(对象)在使用前被初始化
- Item 4:确保变量的初始化 Effective C++笔记
- 《Effective C#》Item 19:推荐在继承中使用接口
- 《Effective C#》Item 19:推荐在继承中使用接口
- MySQL宣布加入微软Visual Studio工业伙伴计划
- 大揭密:微软自己如何测试Windows Vista
- JDBC中rs.next()的思考
- eclipse-如何使用links目录配置插件
- 追求者!
- 《Effective C#》Item 8:确保“0”在值类型中是有效的
- _blank开新窗口不符合标准?
- 如何去掉超链接的下划线?
- 辜勤华:我在犹太公司的15年
- javascript小技巧
- Apache中预创建Preforking MPM 机制剖析(1)
- 使用WSIF进行对BPEL集成
- 一篇实在忍不住转载的经济好文
- 急!! DirectShow 开发 activex 插件问题求助