CA2227: Collection プロパティは読み取り専用でなければなりません
TypeName |
CollectionPropertiesShouldBeReadOnly |
CheckId |
CA2227 |
カテゴリ |
Microsoft.Usage |
互換性に影響する変更点 |
あり |
原因
外部で参照できる書き込み可能なプロパティが、System.Collections.ICollection を実装する型になっています。 配列、インデクサー ('Item' という名前が付くプロパティ)、およびアクセス許可セットは、この規則では無視されます。
規則の説明
書き込み可能なコレクション プロパティにより、ユーザーはコレクションを完全に異なるコレクションで置換できます。 読み取り専用プロパティは、コレクションを置換できないようにしますが、個別のメンバーが設定されることは回避できません。 コレクションの置換が目的である場合は、適切なデザイン パターンとは、すべての要素をコレクションから削除するメソッドおよびコレクションを再構築するメソッドを含めることです。 このパターンの例については、System.Collections.ArrayList クラスの Clear メソッドおよび AddRange メソッドのトピックを参照してください。
バイナリ シリアル化および XML シリアル化は、両方ともコレクションである読み取り専用プロパティをサポートします。 System.Xml.Serialization.XmlSerializer クラスには、ICollection および System.Collections.IEnumerable を実装する型に関して、シリアル化可能にするための 固有の要件があります。
違反の修正方法
この規則の違反を修正するには、プロパティを読み取り専用にします。また、デザイン上必要な場合は、コレクションの追加と再構築を行うメソッドを追加します。
警告を抑制する状況
この規則による警告は抑制しないでください。
使用例
次の例は、書き込み可能なコレクション プロパティを持つ型と、コレクションを直接置換する方法を示しています。 さらに、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);
}