CA2227:集合屬性應該為唯讀
型別名稱 |
CollectionPropertiesShouldBeReadOnly |
CheckId |
CA2227 |
分類 |
Microsoft.Usage |
中斷變更 |
中斷 |
原因
外部可見的可寫入屬性 (Property) 是實作 ICollection 的型別。此規則會忽略陣列、包含名為 'Item' 屬性的索引子 (Indexer),以及使用權限集合。
規則描述
可寫入的集合屬性允許使用者以完全不同的集合來取代該集合。唯讀屬性會從取代過程中停止集合,但是仍然允許設定個別成員。如果目標是取代集合,則慣用的設定模式會包含可從集合中移除所有項目的方法,以及重新填入集合的方法。如需此模式的範例,請參閱 ArrayList 類別的 Clear 和 AddRange 方法。
二進位和 XML 序列化 (Serialization) 都支援唯讀屬性 (屬性為集合)。XmlSerializer 類別具有型別的特定要求,會實作 ICollection 和 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);
}