EffectiveC#7--选择恒定的原子值类型数据
1.恒定类型就是一但它们被创建,它们(的值)就是固定的.
恒定类型可以很好的在基于哈希代码的集合上工作。以Object.GetHashCode()方法返回的值,对同一个实例是必须相同的
2.一个客户类型就不是原子类型;它是由多个不同的恒定的组成部份构成的:地址,名字以及一个电话号码集合。
3. 可变类型:书中举出的例子为地址Address结构的公共属性中提供了set方法。
推荐做法:
public struct Address
{
private readonly string _line1;
private readonly string _line2;
private readonly string _city;
private readonly string _state;
private readonly int _zipCode;
//移除所有的属性设置功能
public string Line1 { get { return _line1; } }
public string Line2 { get { return _line2; } }
public string City { get { return _city; } }
//etc //使用构造函数初始化对象
public Address(string line1, string line2, string city, string state, int zipCode)
{
_line1 = line1;
_line2 = line2;
_city = city;
_state = state;
_zipCode = zipCode;
ValidateState(state);
}
}
使用:
// Create an address:
Address a1 = new Address( "111 S. Main", "", "Anytown", "IL", 61111 );
// To change, re-initialize:
a1 = new Address( a1.Line1, a1.Line2, "Ann Arbor", "MI", 48103 );
这正是期望的安全性:a1要么是默认的原始值,要么是新的值。如果在构造对象时发生了异常,那么a1保持原来的默认值不变。
.Net里的日期时间结构,它就是一个典型的恒定常量例子。它没有提供任何的对单独年,月,日或者星期进行修改的方法。因为单独修改其中一个,可能导致整个日期处于不正确的状态。
为了创建一个恒定类型,你须要确保你的用户没有任何机会来修改内部状态。
值类型不支持派生类所以不必定义担心派生类来修改它的内部状态。
要注意任何在恒定类型内的可变的引用类型字段。当你为这些类型实现了构造函数后,你须要被动的把可变的引用类型COPY一遍
举例:不推荐如下写法,原因是PhoneList内部引用的数组,引用了分配在对象外的数组存储空间上。开发人员可通过另一个引用到这个存储空间上的对象来修改你的恒定结构
public struct PhoneList
{
private readonly Phone[] _phones;
public PhoneList(Phone[] ph)
{
_phones = ph; //注意
}
}
Phone[] phones = new Phone[];
PhoneList pl = new PhoneList( phones );
// Modify the phones also modifies the pl 注意
phones[] = Phone.GeneratePhoneNumber( );
而是这种方案
public struct PhoneList
{
private readonly Phone[] _phones;
public PhoneList(Phone[] ph)
{
_phones = new Phone[ ph.Length ];
// Copies values because Phone is a value type. 注意比较
ph.CopyTo( _phones, );
}
}
Phone[] phones = new Phone[];
PhoneList pl = new PhoneList( phones );
// Modify the phones Does not modify the copy in pl. 注意
phones[] = Phone.GeneratePhoneNumber( );
EffectiveC#7--选择恒定的原子值类型数据的更多相关文章
- EffectiveC#6--区别值类型数据和引用类型数据
1. 设计一个类型时,选择struct或者class是件简单的小事情,但是,一但你的类型发生了改变, 对所有使用了该类型的用户进行更新却要付出(比设计时)多得多的工作. 2.值类型:无多态但性能佳. ...
- EffectiveC#8--确保0对于值类型数据是有效的(初始化问题)
1.决不要创建一个不包括0在内的枚举类型 2.举例如下: public enum Planet { Mercury = 1, Venus = 2, Earth = 3, Mars = 4, Jupit ...
- Symbol ES6 新增的一种值类型数据,表示一种绝不重复的值
let s1 = Symbol(33); let s2 = Symbol(33); alert(typeof(s1)); //数据类型判断 // alert(s1.toString()); //可把一 ...
- CLR via C#深解笔记三 - 基元类型、引用类型和值类型 | 类型和成员基础 | 常量和字段
编程语言的基元类型 某些数据类型如此常用,以至于许多编译器允许代码以简化的语法来操纵它们. System.Int32 a = new System.Int32(); // a = 0 a = 1 ...
- [CLR via C#]5.3 值类型的装箱和拆箱
原文:[CLR via C#]5.3 值类型的装箱和拆箱 在CLR中为了将一个值类型转换成一个引用类型,要使用一个名为装箱的机制. 下面总结了对值类型的一个实例进行装箱操作时内部发生的事: 1)在托管 ...
- C#中的基元类型、值类型和引用类型
C# 中的基元类型.值类型和引用类型 1. 基元类型(Primitive Type) 编译器直接支持的类型称为基元类型.基元类型可以直接映射到 FCL 中存在的类型.例如,int a = 10 中的 ...
- CLR via 笔记 5.3 值类型的装箱和拆箱
1.装箱 为了将一个值类型转换成一个引用类型,要使用一个名为装箱(Boxing)的机制. 1.在托管堆中分配好内存.分配的内存量是值类型的各个字段需要的内存量加上托管堆的所有对象都有的两个额外成员(类 ...
- JavaScript数据类型--值类型和引用类型
值类型:也称为原始数据或原始值(primitive value). 这类值存储在栈(stack)中,栈是内存中一种特殊的数据结构,也称为线性表,栈按照后进先出的原则存储数据,先进入的数据被压入栈底,最 ...
- C#基础知识系列二(值类型和引用类型、可空类型、堆和栈、装箱和拆箱)
前言 之前对几个没什么理解,只是简单的用过可空类型,也是知道怎么用,至于为什么,还真不太清楚,通过整理本文章学到了很多知识,也许对于以后的各种代码优化都有好处. 本文的重点就是:值类型直接存储其值,引 ...
随机推荐
- SDK文件夹下内容介绍
Platform-Tools: 这是 adb, fastboot 等工具包.把解压出来的 platform-tools 文件夹放在 android sdk 根目录下,并把 adb所在的目录添加到系统 ...
- sqlserver2005重新安装(安装汇编错误,安装程序无法连接到数据库服务进行服务配置)
2014-01-09 16:41 1687人阅读 评论(1) 收藏 举报 分类: 数据库(1) 版权声明:本文为博主原创文章,未经博主允许不得转载. sqlserver2005重新安装(安装汇编错误, ...
- 第一次写博客,关于前端开发deMVC在js中的应用
对前端MVC MVC分别是model.view.controller的缩写,模型.视图.控制器.这些更加偏向于后台,在以前MVC是只属于后台的.当然随着技术的进步,前端的大牛们将后台的一些东西应用于前 ...
- C++中的类指针
代码: #include <iostream> #include <string> #include <cstdio> using namespace std; c ...
- Angularjs 日期格式转换
我自己的随笔,记录我编码的点滴. <!DOCTYPE HTML><html><head> <meta charset="utf-8" ...
- 连接SQLite 创建ADO.net实体类
0.开发环境 win10,vs2013-x64 1.安装: sqlite-netFx451-setup-bundle-x86-2013-1.0.102.0.exe 注意事项:选在VisualStudi ...
- 火狐Firefox 浏览器 onblur() 并且alert()时文本被选中问题
说明:镜像是组成在线实验课程的基础环境,教师设计的实验绑定一个或多个镜像,就组成了一讲独立的在线实验课程. 镜像名称: 火狐Firefox 浏览器 onblur() 并且alert()时文本被 ...
- 一个好玩的jq+php实现转盘抽奖程序
前台页面: <!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <met ...
- win8(64位)下memcache安装时报错“ failed to install service or service already installed” 与安装
解决办法: 1.找到cmd.exe文件(c:\windows\system32\cmd.exe) 2.右键cmd.exe以管理员方式运行 3.把php_memcache.dll放到php的ext目录: ...
- MongoDB备份数据库&导入数据库
今天需要对线上的MongoDB中的webpage库进行备份,然后在本地导入备份的库. 1.备份整个MongoDB数据库 mongodump -h dbhost --port 端口 -u 用户名 -p ...