您应该提供更多详细信息,但一个选项是System.Collections.ObjectModel.ReadOnlyCollection<>作为列表/数组.它可以像这样创建:
var immutable1 = Array.AsReadOnly(new[] { 7, 9, 13, });
var immutable2 = (new List<int> { 7, 9, 13, }).AsReadOnly();
Run Code Online (Sandbox Code Playgroud)
它是一个包装器IList<>.它不能转换为允许更改基础列表/数组的任何内容.但当然,可以通过反思来达到基础对象.
如果某个地方的其他人改变了"内部"列表/数组,那么它将在ReadOnlyCollection<>包装器中重新连接.没有复制.
这是一种"浅薄"的不变性形式.如果单个项目可以变异(哪个int不能),则包装器不会禁止这样做.
更便宜的事情就是使用IReadOnlyList<out T>协变的接口T(一个额外的优势).a List<T>和a都T[]实现了这个接口.所以:
IReadOnlyList<int> immutable3 = new[] { 7, 9, 13, };
IReadOnlyList<int> immutable4 = new List<int> { 7, 9, 13, };
Run Code Online (Sandbox Code Playgroud)
然而,在这种情况下,消费者可以测试immutable3 as IList<int>,例如,或者immutable3 as int[]获得可变对象的"可变类型引用"(没有反射).
但是,Microsoft.Immutable.Collections中存在不可变的类型(例如ImmutableList<>).所以你可以考虑安装它,如果你真的需要它.它不是标准.NET库的一部分,因此您必须单独安装它.
为了详细阐述"浅"的含义,假设你有一个数组,其元素类型本身是可变的.那么无论您使用上述哪种建议,人们仍然可以对条目进行调整.例如:
StringBuilder[] yourArray = {
new StringBuilder("All"),
new StringBuilder("is"),
new StringBuilder("good"),
};
var immutable = ImmutableList<StringBuilder>.Empty.AddRange(yourArray);
immutable[0].Insert(0, "NOT ");
immutable[1].Clear();
immutable[2].Append(new string('!', 10000));
Run Code Online (Sandbox Code Playgroud)