欢迎来到天天文库
浏览记录
ID:21769274
大小:44.00 KB
页数:6页
时间:2018-10-24
《二、创建常量、原子性的值类型》由会员上传分享,免费在线阅读,更多相关内容在教育资源-天天文库。
1、6/6创建常量、原子性的值类型创建常量、原子性的值类型概述本文是《EffectiveC#》一书第七节的读书笔记。通过这篇文章,我主要想向大家说明一个我们平时可能不太会注意到的问题:创建具有常量性和原子性的值类型。从类型设计谈起从Class到Struct假如我们要设计一个存储收信人地址的类型(Type),我们管这个类型叫Address。它应该包含这样几个属性:Province省City市Zip邮编要求对Zip的格式进行控制(必须全为数字,且为6位),大家该如何设计呢?我想很多人会写成这样吧:publicclassAddress{pri
2、vatestringprovince;privatestringcity;privatestringzip;publicstringProvince{get{returnprovince;}set{province=value;}}publicstringCity{get{returncity;}set{city=value;}}publicstringZip{get{returnzip;}set{CheckZip(value);//验证格式zip=value;}}//检测是不是正确的zipprivatevoidCheckZip(s
3、tringvalue){stringpattern=@"d{6}";if(!Regex.IsMatch(value,pattern))6/6创建常量、原子性的值类型thrownewException("Zipisinvalid!");}publicoverridestringToString(){returnString.Format("Province:{0},City:{1},Zip:{2}",province,city,zip);}}这里已经存在第一个问题:当我们声明一个类时,更多的是定义一系列相关的操作(或者叫行为、方法)
4、,当然类中也会包含字段和属性,但这些字段通常都是为类的方法所使用,而属性则常用于表示类的状态(比如StringBuilder的Length),类的能力(比如StringBuilder的Capacity),方法进行的状态或者阶段。而定义一个结构时,我们通常仅仅是用它来保存数据,而不提供方法,或者是仅提供对其自身进行操作或者转换的方法,而非对其它类型提供服务的方法。Address不包含任何的方法,它仅仅是将Provice、City、Zip这样的三个数据组织起来成为一个独立的个体,所以最好将其声明为一个Struct而非是一个Class。(
5、这里也有例外的情况:如果Address包含二十个或者更多的字段,则考虑将其声明为Class,因为Class在参数传递时是传引用,而Struct是传值。在数据较小的情况下,传值的效率更高一些;而在数据较大的时候,传引用占据更小的内存空间。)所以我们首先可以将Address声明为一个Struct而非Class。数据不一致的问题我们接下来使用一下刚刚创建的Address类型:Addressa=newAddress();a.Province="陕西";a.City="西安";a.Zip="710068";Console.WriteLine(
6、a.ToString());//Province:陕西,City:西安,Zip:710068看上去是没有问题的,但是回想下类型的定义,在给Zip属性赋值时是有可能抛出异常的,所以我们还是把它放在一个TryCatch语句中,同时我们给Zip赋一个错误的值,看会发生什么:try{a.City="青岛";a.Zip="12345";//这里触发异常a.Province="山东";}catch{}Console.WriteLine(a.ToString());//Province:陕西,City:青岛,Zip:7100686/6创建常量、原
7、子性的值类型结果是出现了数据不一致的问题,当为Zip赋值的时候,因为引发了异常,所以对Zip以及其后的Province的赋值都失败了,但是对City的赋值是成功的。结果就是出现了Provice是陕西,City却是青岛这种情况。即是在赋值Zip时没有引发异常,也会出现问题:在多线程情况下,当当前线程执行到修改了City为“青岛”,但还没有修改Zip和Province的时候(Zip仍为“710068”、Province仍为“陕西”)。如果此时其他线程访问类型实例a,那么也将会读取到不一致的数据。常量性和原子性我们现在已经知道了上面存在的
8、问题,那么接下来该如何改进呢?我们先来看看作者对常量性和原子性给的定义:•对象的原子性:对象的状态是一个整体,如果一个字段改变,其他字段也要同时做出相应改变。简单来说,就是要么不改,要么全改。•对象的常量性:对象的状态一旦确定,就不能
此文档下载收益归作者所有