CA2227: Las propiedades de la colección deben ser de solo lectura

Propiedad Value
Identificador de la regla CA2227
Título Las propiedades de la colección deben ser de solo lectura
Categoría Uso
La corrección es problemática o no problemática Problemático
Habilitado de forma predeterminada en .NET 8 No

Causa

Una propiedad editable visible externamente es de un tipo que implementa System.Collections.ICollection. Esta regla omite las matrices, los indizadores (propiedades con el nombre "Item"), las colecciones inmutables, las colecciones de solo lectura y los conjuntos de permisos.

Descripción de la regla

Una propiedad de colección grabable permite al usuario reemplazar la colección por otra completamente diferente. Una propiedad init-only de solo lectura impide que la colección se reemplace, pero sí permite establecer miembros individuales. Si reemplazar la colección es un objetivo, el modelo de diseño preferido consiste en incluir un método para quitar todos los elementos de la colección y un método para volver a rellenar la colección. Vea los métodos Clear y AddRange de la clase System.Collections.ArrayList para obtener un ejemplo de este patrón.

Tanto la serialización binaria como la de XML admiten propiedades de solo lectura que son colecciones. La clase System.Xml.Serialization.XmlSerializer tiene requisitos específicos para los tipos que implementan ICollection y System.Collections.IEnumerable para ser serializable.

Cómo corregir infracciones

Para corregir una infracción de esta regla, haga que la propiedad init-only sea de solo lectura. Si el diseño lo requiere, agregue métodos para borrar y volver a rellenar la colección.

Cuándo suprimir las advertencias

Puede suprimir la advertencia si la propiedad forma parte de una clase de objeto transferencia de datos (DTO).

De lo contrario, no suprima las advertencias de esta regla.

Supresión de una advertencia

Si solo quiere suprimir una única infracción, agregue directivas de preprocesador al archivo de origen para deshabilitar y volver a habilitar la regla.

#pragma warning disable CA2227
// The code that's violating the rule is on this line.
#pragma warning restore CA2227

Para deshabilitar la regla de un archivo, una carpeta o un proyecto, establezca su gravedad en none del archivo de configuración.

[*.{cs,vb}]
dotnet_diagnostic.CA2227.severity = none

Para obtener más información, consulte Procedimiento para suprimir advertencias de análisis de código.

Ejemplo

En el ejemplo siguiente se muestra un tipo con una propiedad de colección de escritura y se muestra cómo se puede reemplazar la colección directamente. Además, se muestra la manera preferida de reemplazar una propiedad de colección de solo lectura mediante los métodos Clear y AddRange.

public class WritableCollection
{
    public ArrayList SomeStrings
    {
        get;

        // This set accessor violates rule CA2227.
        // To fix the code, remove this set accessor or change it to init.
        set;
    }

    public WritableCollection()
    {
        SomeStrings = new ArrayList(new string[] { "one", "two", "three" });
    }
}

class ReplaceWritableCollection
{
    static void Main2227()
    {
        ArrayList newCollection = new ArrayList(new string[] { "a", "new", "collection" });

        WritableCollection collection = new WritableCollection();

        // This line of code demonstrates how the entire collection
        // can be replaced by a property that's not read only.
        collection.SomeStrings = newCollection;

        // If the intent is to replace an entire collection,
        // implement and/or use the Clear() and AddRange() methods instead.
        collection.SomeStrings.Clear();
        collection.SomeStrings.AddRange(newCollection);
    }
}
Public Class WritableCollection

    ' This property violates rule CA2227.
    ' To fix the code, add the ReadOnly modifier to the property:
    ' ReadOnly Property SomeStrings As ArrayList
    Property SomeStrings As ArrayList

    Sub New()
        SomeStrings = New ArrayList(New String() {"one", "two", "three"})
    End Sub

End Class

Class ViolatingVersusPreferred

    Shared Sub Main2227()
        Dim newCollection As New ArrayList(New String() {"a", "new", "collection"})

        Dim collection As New WritableCollection()

        ' This line of code demonstrates how the entire collection
        ' can be replaced by a property that's not read only.
        collection.SomeStrings = newCollection

        ' If the intent is to replace an entire collection,
        ' implement and/or use the Clear() and AddRange() methods instead.
        collection.SomeStrings.Clear()
        collection.SomeStrings.AddRange(newCollection)
    End Sub

End Class

Vea también