CA2227: Właściwości kolekcji powinny być tylko do odczytu
Właściwości | Wartość |
---|---|
Identyfikator reguły | CA2227 |
Tytuł | Właściwości kolekcji powinny być tylko do odczytu |
Kategoria | Użycie |
Poprawka powodująca niezgodność lub niezgodność | Kluczowa |
Domyślnie włączone na platformie .NET 9 | Nie. |
Przyczyna
Zewnętrznie widoczna, zapisywalna właściwość jest typu, który implementuje System.Collections.ICollection. Ta reguła ignoruje tablice, indeksatory (właściwości o nazwie "Item"), niezmienne kolekcje, kolekcje readonly i zestawy uprawnień.
Opis reguły
Właściwość kolekcji z możliwością zapisu umożliwia użytkownikowi zastąpienie kolekcji zupełnie inną kolekcją. Właściwość tylko do odczytu lub init-only uniemożliwia zastąpienie kolekcji, ale nadal umożliwia ustawienie poszczególnych elementów członkowskich. Jeśli zastąpienie kolekcji jest celem, preferowanym wzorcem projektu jest dołączenie metody w celu usunięcia wszystkich elementów z kolekcji oraz metody ponownego wypełniania kolekcji. Clear Zobacz metody System.Collections.ArrayList i AddRange klasy, aby zapoznać się z przykładem tego wzorca.
Zarówno serializacja binarna, jak i XML obsługują właściwości tylko do odczytu, które są kolekcjami. Klasa System.Xml.Serialization.XmlSerializer ma określone wymagania dotyczące typów implementujących ICollection i System.Collections.IEnumerable w celu serializacji.
Jak naprawić naruszenia
Aby naprawić naruszenie tej reguły, ustaw właściwość tylko do odczytu lub init-only. Jeśli projekt tego wymaga, dodaj metody w celu wyczyszczenia i ponownego wypełniania kolekcji.
Kiedy pomijać ostrzeżenia
Ostrzeżenie można pominąć, jeśli właściwość jest częścią klasy obiektu transferu danych (DTO ).
W przeciwnym razie nie pomijaj ostrzeżeń z tej reguły.
Pomijanie ostrzeżenia
Jeśli chcesz po prostu pominąć pojedyncze naruszenie, dodaj dyrektywy preprocesora do pliku źródłowego, aby wyłączyć, a następnie ponownie włączyć regułę.
#pragma warning disable CA2227
// The code that's violating the rule is on this line.
#pragma warning restore CA2227
Aby wyłączyć regułę dla pliku, folderu lub projektu, ustaw jego ważność na none
w pliku konfiguracji.
[*.{cs,vb}]
dotnet_diagnostic.CA2227.severity = none
Aby uzyskać więcej informacji, zobacz Jak pominąć ostrzeżenia dotyczące analizy kodu.
Przykład
W poniższym przykładzie pokazano typ z właściwością kolekcji z możliwością zapisu i pokazano, jak można bezpośrednio zamienić kolekcję. Ponadto pokazuje preferowany sposób zastępowania właściwości kolekcji tylko do odczytu przy użyciu metod Clear
i 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