Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
| Właściwości | Wartość |
|---|---|
| Identyfikator reguły | CA2227 |
| Tytuł | Właściwości kolekcji powinny być tylko do odczytu |
| Kategoria | Użycie |
| Poprawka łamiąca lub nienaruszająca | Przełomowe |
| Domyślnie włączone na platformie .NET 10 | Nie. |
| Zastosowane języki | C# i Visual Basic |
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żytkownikom zastąpienie kolekcji zupełnie inną kolekcją. Właściwość tylko do odczytu lub init-only zapobiega zastąpieniu kolekcji, ale nadal umożliwia ustawienie poszczególnych członków. Jeśli zastąpienie kolekcji jest celem, preferowanym wzorcem projektu jest dołączenie metody w celu usunięcia wszystkich elementów z kolekcji i metody ponownego wypełniania kolekcji. Clear Zobacz metody AddRange i System.Collections.ArrayList 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, które implementują ICollection i System.Collections.IEnumerable, aby były serializowalne.
Jak naprawić naruszenia
Aby naprawić naruszenie tej reguły, użyj jednej z następujących metod:
Skonfiguruj właściwość jako tylko do odczytu lub tylko do inicjalizacji. Właściwość tylko do odczytu lub init-only zapobiega wymianie kolekcji, jednocześnie zezwalając na ustawianie poszczególnych członków. Jeśli projekt wymaga zastąpienia zawartości kolekcji, dodaj metody w celu wyczyszczenia i ponownego wypełniania kolekcji. Aby zapoznać się z przykładem tego wzorca, zobacz metody ArrayList.Clear i ArrayList.AddRange.
Zmień typ właściwości na typ kolekcji tylko do odczytu. Jeśli osoby wywołujące nie muszą modyfikować kolekcji, zmień typ właściwości na kolekcję tylko do odczytu, taką jak ReadOnlyCollection<T>. Takie podejście sprawia, że zamiar wyłącznie do odczytu jest jawny w sygnaturze typu.
Zmień typ właściwości na typ kolekcji współbieżnej bezpieczny wątkowo, zachowując właściwość tylko do odczytu. Jeśli projekt wymaga, aby wiele wątków modyfikowało kolekcję współbieżnie, uwidacznia właściwość tylko do odczytu (bez ustawiacza), której typem jest kolekcja współbieżna, taka jak ConcurrentBag<T>. CA2227 jest wyzwalany przez właściwość kolekcji z możliwością zapisu, a nie przez typ kolekcji, więc taka właściwość musi pozostać tylko do odczytu. Wybór współbieżnej kolekcji dotyczy tylko bezpiecznych dla wątków zmian zwróconego egzemplarza 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ą zapisywalnej kolekcji i jak można bezpośrednio zastąpić kolekcję. Przedstawiono również 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 = ["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