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());
使用不可变对象,我们有以下好处:
它将处于已知状态(其他代码无法更改)。
这是线程安全的。
构造函数为验证提供了一个地方。
知道对象不能被更改会使代码更易于理解。