在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
Effective C# Item 8 : Ensure That 0 Is a Valid State for Value Types .Net中默认的初始化是将对象的所有信息都置0。对于值类型来说,我们不能避免在创建新的值类型实例的时候将其值置为0。这是类型的默认值。 唯一一个特殊情况是枚举(enum)。我们不应该创建一个不包含0作为其值的枚举。所有的枚举都继承自System.ValueType。枚举值是从0开始的,但是我们可以修改它:(P.S. 虽然现在Pluto已经不是太阳系的一员了,bless一下)
public enum Planet
Planet(); 现在sphere的值就是0,这不是一个合法的值。虽然不会报错,但是0并不代表任何含义。当我们创建自己的引用时,应当确保0是其中的一个枚举值。如果你将枚举声明为二进制类型的,需要定义0来代表None。 如果这样发展下去的话,我们只能强迫用户在初始化的时候就为其明确赋值。
Planet sphere = Planet.Mars;
这将使得我们很难在其他的类型中使用这种类型,因为我们并不知道要将其初始化为何值。 使用这样的类型创建对象将会创建一个不合法的Planet。
ObservationData d = new ObservationData();
我们必须确保0是一个有效的值。如果可以的话应当将其对应为为最佳默认值。对于Planet枚举来说,没有什么最佳可言。当用户没有使用的时候,它应当不包含任何含义。我们可以使用0来改造我们的枚举使其更加合理:
public enum Planet
Planet(); sphere现在对应的枚举值是None,代表还没有用户数据。在这里添加默认值对ObservationData造成的影响就是新初始化的对象的枚举值是0,代表的含义是None。之后可以在ObservationData的构造函数中对其进行修改。要注意的是默认的构造函数仍然有效。用户可以构造一个默认值的对象,我们不能阻止他们这样做。 在我们结束enum的讨论之前,我们还有必要说一下在使用flag的时候枚举的一些特殊情况。使用Flags属性时我们应当将代表None含义的枚举值设为0:(P,S.关于Flags枚举的情况请看我写的另一篇介绍:FlagsAttribute属性在enum中的应用)
[Flags]
public enum Styles } 许多开发者通过二进制操作符&来使用flags枚举。不合理的0值会造成严重的问题,如果flag为0值则下例中的条件会永远不能成立:
if((flag & Styles.Flat) != 0)
DoSth(); //如果flag为0则永远不会执行 因此如果使用Flags,我们应当确定0代表的含义是None。 另外的常见初始化问题发生在值类型中包含的引用类型上。String就是一个常见的例子(P.S. .Net中string是引用类型,虽然某些操作符的重载会给用户带来值类型的错觉)。
public struct LogMessage
LogMessage(); MyMessage包含了一个为null的引用类型。这样并不会引起任何问题。但是当你使用属性来获取它的值的时候就可能会出现问题。因此我们要为其添加如果为null则返回string.Empty的逻辑。在我们的结构中我们应当这样检验属性是否为null。
public struct LogMessage
} 系统初始化时所有的类型的值都为0,这是不能避免的。可能的话应当将0设为最初的默认值。特殊情况下,例如flags枚举,应当让其代表None。 |
请发表评论