CA2227: свойства коллекции должны иметь параметр "только для чтения"
TypeName |
CollectionPropertiesShouldBeReadOnly |
CheckId |
CA2227 |
Категория |
Microsoft.Usage |
Критическое изменение |
Критическое изменение |
Причина
Внешне видимое свойство, допускающее запись, является типом, реализующим ICollection.Массивы, индексы (свойства с именем "Item") и наборы разрешений этим правилом не учитываются.
Описание правила
Свойство коллекции, допускающее запись, позволяет пользователю заменять коллекцию полностью другой коллекцией.Свойство только для чтения предотвращает замену коллекции, но по-прежнему допускает установку, настройку отдельных членов.Если замена коллекции является целью, предпочтительным вариантом разработки будет включение метода для удаления всех элементов из коллекции, а также метода для повторного заполнения коллекции.Пример такого шаблона см. в методах Clear и AddRange класса ArrayList.
Как двоичная, так и XML-сериализация поддерживает свойства только для чтения, являющиеся коллекциями.Класс 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);
}