Поделиться через


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);
}

Связанные правила

CA1819: свойства не должны возвращать массивы