CA2227:集合属性应为只读
属性 | 值 |
---|---|
规则 ID | CA2227 |
标题 | 集合属性应为只读 |
类别 | 使用情况 |
修复是中断修复还是非中断修复 | 重大 |
在 .NET 9 中默认启用 | 否 |
原因
外部可见的可写属性属于实现 System.Collections.ICollection 的类型。 此规则将忽略数组、索引器(名称为“Item”的属性)、不可变集合、只读集合和权限集。
规则说明
使用可写的集合属性,用户可以将该集合替换为完全不同的集合。 只读或 init-only 属性禁止替换该集合,但仍允许设置单个成员。 如果目标是替换集合,则首选的设计模式是包含一个从集合中移除所有元素的方法,以及一个重新填充集合的方法。 有关此情况的示例,请参阅 System.Collections.ArrayList 类的 Clear 和 AddRange 方法。
二进制和 XML 序列化都支持作为集合的只读属性。 为了实现可序列化,System.Xml.Serialization.XmlSerializer 类对实现 ICollection 和 System.Collections.IEnumerable 的类型具有特定的要求。
如何解决冲突
若要解决此规则的冲突,请将属性设置为只读或 init-only。 如果设计需要,请添加方法以清除集合并重新填充。
何时禁止显示警告
如果属性是数据传输对象 (DTO) 类的一部分,则可禁止显示警告。
否则,请不要禁止显示此规则的警告。
抑制警告
如果只想抑制单个冲突,请将预处理器指令添加到源文件以禁用该规则,然后重新启用该规则。
#pragma warning disable CA2227
// The code that's violating the rule is on this line.
#pragma warning restore CA2227
若要对文件、文件夹或项目禁用该规则,请在配置文件中将其严重性设置为 none
。
[*.{cs,vb}]
dotnet_diagnostic.CA2227.severity = none
有关详细信息,请参阅如何禁止显示代码分析警告。
示例
下面的示例演示一个具有可写集合属性的类型,并演示如何直接替换该集合。 此外,它还演示了使用 Clear
和 AddRange
方法替换只读集合属性的首选方式。
public class WritableCollection
{
public ArrayList SomeStrings
{
get;
// This set accessor violates rule CA2227.
// To fix the code, remove this set accessor or change it to init.
set;
}
public WritableCollection()
{
SomeStrings = new ArrayList(new string[] { "one", "two", "three" });
}
}
class ReplaceWritableCollection
{
static void Main2227()
{
ArrayList newCollection = new ArrayList(new string[] { "a", "new", "collection" });
WritableCollection collection = new WritableCollection();
// This line of code demonstrates how the entire collection
// can be replaced by a property that's not read only.
collection.SomeStrings = newCollection;
// If the intent is to replace an entire collection,
// implement and/or use the Clear() and AddRange() methods instead.
collection.SomeStrings.Clear();
collection.SomeStrings.AddRange(newCollection);
}
}
Public Class WritableCollection
' This property violates rule CA2227.
' To fix the code, add the ReadOnly modifier to the property:
' ReadOnly Property SomeStrings As ArrayList
Property SomeStrings As ArrayList
Sub New()
SomeStrings = New ArrayList(New String() {"one", "two", "three"})
End Sub
End Class
Class ViolatingVersusPreferred
Shared Sub Main2227()
Dim newCollection As New ArrayList(New String() {"a", "new", "collection"})
Dim collection As New WritableCollection()
' This line of code demonstrates how the entire collection
' can be replaced by a property that's not read only.
collection.SomeStrings = newCollection
' If the intent is to replace an entire collection,
' implement and/or use the Clear() and AddRange() methods instead.
collection.SomeStrings.Clear()
collection.SomeStrings.AddRange(newCollection)
End Sub
End Class