[c#] 불변 클래스는 어떻게 만듭니 까?

불변 클래스를 만드는 중입니다.
모든 속성을 읽기 전용으로 표시했습니다.

수업에 항목 목록이 있습니다.
속성이 읽기 전용 인 경우 목록을 수정할 수 있습니다.

목록의 IEnumerable을 노출하면 변경할 수 없습니다.
클래스를 불변으로 만들기 위해 따라야하는 기본 규칙이 무엇인지 알고 싶었습니다.



답변

나는 당신이 올바른 길을 가고 있다고 생각합니다.

  • 클래스에 주입 된 모든 정보는 생성자에 제공되어야합니다.
  • 모든 속성은 getter 여야합니다.
  • 컬렉션 (또는 배열)이 생성자에 전달되면 호출자가 나중에 수정하지 못하도록 복사해야합니다.
  • 컬렉션을 반환하려면 복사본 또는 읽기 전용 버전을 반환합니다 (예 : ArrayList.ReadOnly 또는 이와 유사한 사용)-이것을 이전 지점과 결합하고 다음 경우에 반환 될 읽기 전용 복사본을 저장할 수 있습니다. 호출자가 액세스), 열거자를 반환하거나 컬렉션에 대한 읽기 전용 액세스를 허용하는 다른 메서드 / 속성을 사용합니다.
  • 멤버 중 하나라도 변경 가능한 경우 여전히 변경 가능한 클래스의 모양을 가질 수 있습니다.이 경우 유지하려는 상태를 복사하고 전체 변경 가능한 객체를 복사하지 않는 한 반환하지 않아야합니다. 호출자에게 돌려주기 전에-또 다른 옵션은 변경 가능한 객체의 변경 불가능한 “섹션”만 반환하는 것입니다. @Brian Rasmussen 덕분에이 점을 확장 할 수 있습니다.

답변

변경 불가능하게하려면 모든 속성과 필드가 읽기 전용이어야합니다. 그리고 모든 목록의 항목은 그 자체로 불변이어야합니다.

다음과 같이 읽기 전용 목록 속성을 만들 수 있습니다.

public class MyClass
{
    public MyClass(..., IList<MyType> items)
    {
        ...
        _myReadOnlyList = new List<MyType>(items).AsReadOnly();
    }

    public IList<MyType> MyReadOnlyList
    {
        get { return _myReadOnlyList; }
    }
    private IList<MyType> _myReadOnlyList

}


답변

또한 다음 사항에 유의하십시오.

public readonly object[] MyObjects;

readonly 키워드로 표시된 경우에도 변경 불가능하지 않습니다. 인덱스 접근 자별로 개별 배열 참조 / 값을 변경할 수 있습니다.


답변

ReadOnlyCollection수업을 사용하십시오 . 그것은에 위치하고있어 System.Collections.ObjectModel공간.

목록 (또는 생성자)을 반환하는 모든 항목에서 목록을 읽기 전용 컬렉션으로 설정합니다.

using System.Collections.ObjectModel;

...

public MyClass(..., List<ListItemType> theList, ...)
{
    ...
    this.myListItemCollection= theList.AsReadOnly();
    ...
}

public ReadOnlyCollection<ListItemType> ListItems
{
     get { return this.myListItemCollection; }
}


답변

또 다른 옵션은 내부 컬렉션을 전혀 노출하는 대신 방문자 패턴을 사용하는 것입니다.


답변

ReadOnlyCollection 을 사용하면 클라이언트가 수정하는 것을 제한합니다.


답변