我正在创建一个不可变的类。
我已将所有属性标记为只读。
我有一个班级项目清单。
虽然如果属性是只读的,则可以修改列表。
公开列表的 IEnumerable 使其不可变。
我想知道使类不可变必须遵循的基本规则是什么?
我正在创建一个不可变的类。
我已将所有属性标记为只读。
我有一个班级项目清单。
虽然如果属性是只读的,则可以修改列表。
公开列表的 IEnumerable 使其不可变。
我想知道使类不可变必须遵循的基本规则是什么?
我认为你在正确的轨道上-
为了不可变,您的所有属性和字段都应该是只读的。任何列表中的项目本身都应该是不可变的。
您可以按如下方式创建只读列表属性:
public class MyClass
{
public MyClass(..., IList<MyType> items)
{
...
_myReadOnlyList = new List<MyType>(items).AsReadOnly();
}
public IList<MyType> MyReadOnlyList
{
get { return _myReadOnlyList; }
}
private IList<MyType> _myReadOnlyList
}
另外,请记住:
public readonly object[] MyObjects;
即使用 readonly 关键字标记也不是不可变的。您仍然可以通过索引访问器更改单个数组引用/值。
使用ReadOnlyCollection
类。它位于System.Collections.ObjectModel
命名空间中。
在返回列表(或在构造函数中)的任何内容上,将列表设置为只读集合。
using System.Collections.ObjectModel;
...
public MyClass(..., List<ListItemType> theList, ...)
{
...
this.myListItemCollection= theList.AsReadOnly();
...
}
public ReadOnlyCollection<ListItemType> ListItems
{
get { return this.myListItemCollection; }
}
您只需要 L...Ehmrecord
和C# 9.0或更高版本。
public record Customer(string FirstName, string LastName, IEnumerable<string> Items);
//...
var person = new Customer("Test", "test", new List<string>() { "Test1", "Test2", "Test3" });
// you can't change anything within person variable
// person.FirstName = "NewName";
这将被转换为名为 Customer 的不可变类,具有三个FirstName
属性LastName
和Items
。
如果您需要一个不可变(只读)集合作为类的属性,最好将其IEnumerable<T>
公开ReadOnlyCollection<T>
为System.Collections.Immutable
另一种选择是使用访问者模式,而不是暴露任何内部集合。
使用ReadOnlyCollection将限制客户端对其进行修改。
最初的问答日期是 2008 年底,现在有一个System.Collections.Immutable 命名空间,我相信它可以追溯到最早的 .NET Core (1.0) 。命名空间在 .NET Standard(当前版本 2.1)和 .NET Framework(当前版本 4.8)中仍然不可用。这个命名空间有很多不可变的集合,包括在原始问题中询问的ImmutableList 。但是,我相信 System.Collections.Immutable 命名空间可能会出现在 .NET 5 中,而 .NET 5 目前处于候选版本 2 中。
此外,从 C# 6 开始,您只需使用{ get;就可以拥有不可变的自动实现属性。}。