다음을 통해 공유


CA2227: 컬렉션 속성은 읽기 전용이어야 합니다.

속성
규칙 ID CA2227
제목 컬렉션 속성은 읽기 전용이어야 합니다.
범주 사용 현황
수정 사항이 기능을 손상시키는지, 아니면 비손상적인지 주요 변경
.NET 10에서 기본적으로 사용하도록 설정 아니요
적용 가능한 언어 C# 및 Visual Basic

원인

외부에서 볼 수 있는 쓰기 가능 속성은 System.Collections.ICollection을 구현하는 형식입니다. 이 규칙은 배열, 인덱서(이름이 ‘항목’ 인 속성), 변경할 수 없는 컬렉션, 읽기 전용 컬렉션, 권한 집합을 무시합니다.

규칙 설명

쓰기 가능한 컬렉션 속성을 사용하면 사용자가 컬렉션을 완전히 다른 컬렉션으로 바꿀 수 있습니다. 읽기 전용 또는 init 전용 속성을 사용하면 컬렉션을 바꿀 수 없지만 개별 멤버를 설정할 수 있습니다. 컬렉션을 바꾸는 것이 목표인 경우 기본 디자인 패턴은 컬렉션에서 모든 요소를 제거하는 메서드와 컬렉션을 다시 채워야 하는 메서드를 포함하는 것입니다. 이 패턴의 예는 Clear 클래스의 AddRange 메서드 및 System.Collections.ArrayList 메서드를 참조하세요.

이진 및 XML serialization은 모두 컬렉션인 읽기 전용 속성을 지원합니다. 클래스에는 System.Xml.Serialization.XmlSerializerICollection를 구현하는 형식이 직렬화될 수 있도록 하는 특정 요구 사항이 있습니다.

위반 문제를 해결하는 방법

다음 방법 중 하나를 사용하여 이 규칙 위반 문제를 해결합니다.

  • 속성을 읽기 전용 또는 init 전용으로 만듭니다. 읽기 전용 또는 초기화 전용 속성은 개별 멤버를 설정할 수 있도록 허용하면서 컬렉션을 바꿀 수 없도록 합니다. 디자인에서 컬렉션의 내용을 바꿔야 하는 경우 메서드를 추가하여 컬렉션을 지우고 다시 채웁니다. 이 패턴의 예제를 보려면 ArrayList.ClearArrayList.AddRange 메서드를 참조하세요.

  • 속성 형식을 읽기 전용 컬렉션 형식으로 변경합니다. 호출자가 컬렉션을 수정할 필요가 없는 경우 속성 형식을 읽기 전용 컬렉션(예: .)으로 ReadOnlyCollection<T>변경합니다. 이 방법은 형식 서명에서 읽기 전용 의도를 명시적으로 만듭니다.

  • 속성을 읽기 전용으로 유지하면서 속성 형식을 스레드로부터 안전한 동시 컬렉션 형식으로 변경합니다. 디자인에서 컬렉션을 동시에 수정하기 위해 여러 스레드가 필요한 경우 형식이 동시 컬렉션 ConcurrentBag<T>인 읽기 전용 속성(setter 없음)을 노출합니다. CA2227은 컬렉션 형식이 아닌 쓰기 가능한 컬렉션 속성에 의해 트리거되므로 속성은 읽기 전용이어야 합니다. 반환된 컬렉션 인스턴스의 스레드 안전한 변경만을 지원하는 것이 동시 컬렉션 선택의 역할입니다.

경고를 표시하지 않는 경우

속성이 DTO(데이터 전송 개체) 클래스의 일부인 경우 경고를 표시하지 않을 수 있습니다.

그렇지 않으면 이 규칙의 경고를 억제하지 마세요.

경고 표시 안 함

단일 위반만 억제하고 싶다면 원본 파일에 전처리기 지시문을 추가하여 규칙을 비활성화한 후 다시 활성화하십시오.

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

파일, 폴더 또는 프로젝트에 대한 규칙을 사용하지 않으려면 none에서 의 심각도를 설정합니다.

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

자세한 내용은 방법: 코드 분석 경고 표시 안 함을 참조하세요.

예시

다음 예제에서는 쓰기 가능한 컬렉션 속성이 있는 형식과 컬렉션을 직접 바꿀 수 있는 방법을 보여 있습니다. 읽기 전용 컬렉션 속성을 대체하기 위한 방법으로 ClearAddRange 메서드를 사용하는 선호되는 방식을 보여줍니다.

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

참고하기