CA2227:集合属性应为只读

类型名

CollectionPropertiesShouldBeReadOnly

CheckId

CA2227

类别

Microsoft.Usage

是否重大更改

原因

在外部可见的可写属性是实现 System.Collections.ICollection 的类型。 数组、索引器(名为“Item”的属性)和权限集都将被该规则忽略。

规则说明

使用可写的集合属性,用户可以将该集合替换为完全不同的集合。 只读属性禁止替换该集合,但仍允许设置单个成员。 如果将替换该集合作为一个目标,则首选的设计模式是包括两个方法,一个用来移除该集合中的所有元素,另一个用来重新填充该集合。 有关此模式的示例,请参见 System.Collections.ArrayList 类的 ClearAddRange 方法。

二进制序列化和 XML 序列化均支持作为集合的只读属性。 对于实现 ICollectionSystem.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);
}

相关规则

CA1819:属性不应返回数组