ReadOnlyCollection<char>是不可变的吗?

4

使用下面的代码会产生CA2104(不要声明只读可变引用类型)警告

public readonly ReadOnlyCollection<char> IllegalChars;

带有部分错误信息

将该字段更改为不可变引用类型之一。如果引用类型“ReadOnlyCollection”实际上是不可变的,请排除此消息。

我确定ReadOnlyCollection是不可变的,但我的问题是是否有一种类型可以使用,以避免出现此消息?

2个回答

4
您可以将公共字段重写为属性:
public ReadOnlyCollection<char> IllegalChars { get; private set; }

或者排除代码分析警告,因为集合无法更改。问题在于FxCop无法检测到ReadOnlyCollection<T>实际上是不可变的。


如果它是不可变的,那么它成为属性的原因是什么? - user34537
是的,将来您可能希望在返回 ReadOnlyCollection<> 之前让 IllegalChars 做一些额外的工作。如果 IllegalChars 是字段,您无法这样做。 - LukeH

2

我相信ReadOnlyCollection是不可变的。

从某种意义上说,它是不可变的,因为你不能改变它所包装的集合,也不能通过它来改变该集合。

但从另一方面来看,由于ReadOnlyCollection是一个包装器,因此可以通过改变底层集合来改变它:

var list = new List<char>{ 'a', 'b', 'c' };
var ro = new ReadOnlyCollection<char>(list);
list.Add('d');
Console.WriteLine(string.Join(",", ro)); // a,b,c,d

然而,您肯定可以拥有一个在实践中是不可变的ReadOnlyCollection,方法是不在任何地方引用基础集合(最简单的方法是在构造时对其进行复制,或者仅在第一次构造只读包装器时构造该集合,然后不再有另一个引用)。
这样做将意味着您保持了CA2104的精神,因为您免受它旨在帮助您避免的问题的影响。然后可以合理地抑制警告。
我会谨慎使用公共字段,更喜欢属性,除非我确实确定要使用字段,但这是另一回事。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接