Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
| Propriété | Valeur |
|---|---|
| Identificateur de la règle | CA2227 |
| Titre | Les propriétés de collection doivent être en lecture seule |
| Catégorie | Utilisation |
| Le correctif a un effet disruptif ou non disruptif | Rupture |
| Activé par défaut dans .NET 10 | Non |
| Langues applicables | C# et Visual Basic |
Cause
Une propriété accessible en écriture et visible en externe est d’un type qui implémente System.Collections.ICollection. Cette règle ignore les tableaux, les indexeurs (propriétés nommées « Item »), les collections immuables, les collections en lecture seule et les ensembles d’autorisations.
Description de la règle
Une propriété de collection accessible en écriture permet aux utilisateurs de remplacer la collection par une collection complètement différente. Une propriété en lecture seule ou init uniquement empêche le remplacement de la collection, mais permet toujours à des membres individuels d’être définis. Si le remplacement de la collection est un objectif, le modèle de conception préféré consiste à inclure une méthode pour supprimer tous les éléments de la collection et une méthode pour remplir à nouveau la collection. Pour obtenir un exemple de ce modèle, consultez les méthodes Clear et AddRange de la classe System.Collections.ArrayList.
La sérialisation binaire et la sérialisation XML prennent toutes deux en charge les propriétés en lecture seule qui sont des collections. La classe System.Xml.Serialization.XmlSerializer a des exigences spécifiques pour que les types qui implémentent ICollection et System.Collections.IEnumerable soient sérialisables.
Comment corriger les violations
Utilisez l’une des approches suivantes pour corriger une violation de cette règle :
Définissez la propriété en lecture seule ou uniquement à l'initialisation. Une propriété en lecture seule ou init uniquement empêche le remplacement de la collection tout en autorisant la définition de membres individuels. Si la conception nécessite de remplacer le contenu de la collection, ajoutez des méthodes pour effacer et remplir à nouveau la collection. Pour un exemple de ce modèle, consultez les méthodes ArrayList.Clear et ArrayList.AddRange.
Remplacez le type de propriété par un type de collection en lecture seule. Si les appelants n’ont pas besoin de modifier la collection, remplacez le type de propriété par une collection en lecture seule, par exemple ReadOnlyCollection<T>. Cette approche rend l’intention en lecture seule explicite dans la signature de type.
Remplacez le type de propriété par un type de collection concurrente sécurisé pour les threads, tout en conservant la propriété en lecture seule. Si la conception nécessite plusieurs threads pour modifier la collection simultanément, exposez une propriété en lecture seule (aucun setter) dont le type est une collection simultanée, telle que ConcurrentBag<T>. CA2227 est déclenché par une propriété de collection modifiable, et non par le type de collection, c'est pourquoi la propriété doit toujours être en mode lecture seule. Le choix de collection simultané traite uniquement la mutation thread-safe de l’instance de collection retournée.
Quand supprimer les avertissements
Vous pouvez supprimer l’avertissement si la propriété fait partie d’une classe DTO (Data Transfer Object).
Sinon, ne supprimez pas les avertissements de cette règle.
Supprimer un avertissement
Si vous voulez supprimer une seule violation, ajoutez des directives de préprocesseur à votre fichier source pour désactiver et réactiver la règle.
#pragma warning disable CA2227
// The code that's violating the rule is on this line.
#pragma warning restore CA2227
Pour désactiver la règle sur un fichier, un dossier ou un projet, définissez sa gravité sur none dans le fichier de configuration.
[*.{cs,vb}]
dotnet_diagnostic.CA2227.severity = none
Pour plus d’informations, consultez Comment supprimer les avertissements de l’analyse de code.
Exemple
L’exemple suivant montre un type avec une propriété de collection accessible en écriture et comment remplacer la collection directement. Cela montre également la méthode recommandée pour remplacer une propriété de collection en lecture seule à l'aide des méthodes Clear et 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 = ["a", "new", "collection"];
WritableCollection collection = new()
{
// This line of code demonstrates how the entire collection
// can be replaced by a property that's not read only.
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