CA2227:集合属性应为只读
类型名 |
CollectionPropertiesShouldBeReadOnly |
CheckId |
CA2227 |
类别 |
Microsoft.Usage |
是否重大更改 |
是 |
原因
在外部可见的可写属性是实现 System.Collections.ICollection 的类型。 数组、索引器(名为“Item”的属性)和权限集都将被该规则忽略。
规则说明
使用可写的集合属性,用户可以将该集合替换为完全不同的集合。 只读属性禁止替换该集合,但仍允许设置单个成员。 如果将替换该集合作为一个目标,则首选的设计模式是包括两个方法,一个用来移除该集合中的所有元素,另一个用来重新填充该集合。 有关此模式的示例,请参见 System.Collections.ArrayList 类的 Clear 和 AddRange 方法。
二进制序列化和 XML 序列化均支持作为集合的只读属性。 对于实现 ICollection 和 System.Collections.IEnumerable,以便可序列化的类型,System.Xml.Serialization.XmlSerializer 类有特定要求。
如何解决冲突
若要修复与该规则的冲突,请将该属性设置为只读,如果设计需要的话,还添加一些用来清除和重新填充该集合的方法。
何时禁止显示警告
不要禁止显示此规则发出的警告。
示例
下面的示例演示一个具有可写集合属性的类型并演示如何直接替换该集合。 另外,还演示了使用 Clear 和 AddRange 方法替换只读集合属性的首选方式。
Imports System
Imports System.Collections
Namespace UsageLibrary
Public Class WritableCollection
Dim strings As ArrayList
Property SomeStrings As ArrayList
Get
Return strings
End Get
' Violates the rule.
Set
strings = Value
End Set
End Property
Sub New()
strings = New ArrayList( _
New String() {"IEnumerable", "ICollection", "IList"} )
End Sub
End Class
Class ViolatingVersusPreferred
Shared Sub Main()
Dim newCollection As New ArrayList( _
New String() {"a", "new", "collection"} )
' strings is directly replaced with newCollection.
Dim collection As New WritableCollection()
collection.SomeStrings = newCollection
' newCollection is added to the cleared strings collection.
collection.SomeStrings.Clear()
collection.SomeStrings.AddRange(newCollection)
End Sub
End Class
End Namespace
using System;
using System.Collections;
namespace UsageLibrary
{
public class WritableCollection
{
ArrayList strings;
public ArrayList SomeStrings
{
get { return strings; }
// Violates the rule.
set { strings = value; }
}
public WritableCollection()
{
strings = new ArrayList(
new string[] {"IEnumerable", "ICollection", "IList"} );
}
}
class ReplaceWritableCollection
{
static void Main()
{
ArrayList newCollection = new ArrayList(
new string[] {"a", "new", "collection"} );
// strings is directly replaced with newCollection.
WritableCollection collection = new WritableCollection();
collection.SomeStrings = newCollection;
// newCollection is added to the cleared strings collection.
collection.SomeStrings.Clear();
collection.SomeStrings.AddRange(newCollection);
}
}
}
using namespace System;
using namespace System::Collections;
namespace UsageLibrary
{
public ref class WritableCollection
{
public:
// Violates the rule.
property ArrayList^ SomeStrings;
WritableCollection()
{
SomeStrings = gcnew ArrayList(
gcnew array<String^> {"IEnumerable", "ICollection", "IList"} );
}
};
}
using namespace UsageLibrary;
void main()
{
ArrayList^ newCollection = gcnew ArrayList(
gcnew array<String^> {"a", "new", "collection"} );
// strings is directly replaced with newCollection.
WritableCollection^ collection = gcnew WritableCollection();
collection->SomeStrings = newCollection;
// newCollection is added to the cleared strings collection.
collection->SomeStrings->Clear();
collection->SomeStrings->AddRange(newCollection);
}