不变性
不可变性在函数式编程中很常见,在面向对象编程中很少见。
例如,创建一个具有可变状态的地址类型:
public class Address ()
{
public string Line1 { get; set; }
public string Line2 { get; set; }
public string City { get; set; }
}
任何代码都可以改变上述对象中的任何属性。
现在创建不可变的地址类型:
public class Address ()
{
public readonly string Line1;
public readonly string Line2;
public readonly string City;
public Address(string line1, string line2, string city)
{
Line1 = line1;
Line2 = line2;
City = city;
}
}
请记住,拥有只读集合并不尊重不变性。例如,
public class Classroom
{
public readonly List<Student> Students;
public Classroom(List<Student> students)
{
Students = students;
}
}
不是不可变的,因为对象的用户可以改变集合(从中添加或删除元素)。为了使它不可变,人们要么使用像 IEnumerable 这样的接口,它不公开要添加的方法,要么使它成为 ReadOnlyCollection。
public class Classroom
{
public readonly ReadOnlyCollection<Student> Students;
public Classroom(ReadOnlyCollection<Student> students)
{
Students = students;
}
}
List<Students> list = new List<Student>();
// add students
Classroom c = new Classroom(list.AsReadOnly());
使用不可变对象,我们有以下好处:
- 它将处于已知状态(其他代码无法更改)。
- 它是线程安全的。
- 构造函数提供了一个验证位置。
- 知道无法更改对象使代码更容易理解。