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[10];  
PhoneList pl = new PhoneList( phones ); 
// Modify the phones also modifies the pl 注意
phones[5] = 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, 0 ); 
    }
}
Phone[] phones = new Phone[10];  
PhoneList pl = new PhoneList( phones ); 
// Modify the phones Does not modify the copy in pl.   注意
phones[5] = Phone.GeneratePhoneNumber( );

 

  

posted @ 2015-10-10 23:10  王乐  阅读(235)  评论(0编辑  收藏  举报