C#不变性
示例
不变性在函数式编程中很常见,而在面向对象的编程中则很少。
例如,创建具有可变状态的地址类型:
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>();
//添加学生
Classroom c = new Classroom(list.AsReadOnly());使用不可变对象,我们有以下好处:
它将处于已知状态(其他代码无法更改)。
这是线程安全的。
构造函数为验证提供了一个地方。
知道对象不能被更改会使代码更易于理解。