문제

다음 수업이 있습니다.

class SampleClass
{
   private ArrayList mMyList;

   SampleClass()
   {
       // Initialize mMyList
   }

   public ArrayList MyList
   {
       get { return mMyList;}
   }
}

나는 사용자가 mmylist를 얻을 수 있기를 원하기 때문에 속성을 통해 "get"을 노출했지만 개체 (예 : mylist.add (new class ());)에 대한 변경을 원하지 않습니다. 내 수업으로 돌아가는 길.

객체의 사본을 반환 할 수는 있지만 느리게 될 수 있으며 사용자에게 반환 된 값을 재산.

이게 가능해?

도움이 되었습니까?

해결책

배열 목록을 사용하면 BCL에 Readonly Non-Generic Collection 클래스가 없기 때문에 상당히 제한적입니다. 빠르고 더러운 솔루션은 유형의 ienumerable을 반환하는 것입니다.

   public IEnumerable MyList
   {
       get { return mMyList;}
   }

이것은 실제로 누군가가 Arraylist에 캐스팅하는 것을 막지는 않지만 기본적으로도 편집을 허용하지 않습니다.

ArrayList.ReadOnly를 호출하여 효과적으로 읽기 쉬운 목록을 반환 할 수 있습니다. 그러나 반환 유형은 배열리스트이므로 사용자는 여전히 .add로 컴파일 할 수 있지만 런타임 오류가 발생합니다.

다른 팁

사용 ArrayList.ReadOnly () 목록 주위에 읽기 전용 래퍼를 구성하고 반환하는 메소드. 목록을 복사하지는 않지만 그 주위에 읽기 전용 랩퍼를 만듭니다. 컴파일 타임 확인을 받으려면 @jared가 제안한 것처럼 읽기 전용 래퍼를 ienumerable로 반환하고 싶을 것입니다.

public IEnumerable MyList
{
     get { return ArrayList.ReadOnly(mMyList); }
}

읽기 전용 컬렉션은 단순히 컬렉션 수정을 방지하는 래퍼가있는 컬렉션입니다. 기본 컬렉션이 변경되면 읽기 전용 컬렉션은 이러한 변경 사항을 반영합니다.

이 방법은 O (1) 작업입니다.

참조

Jaredpar의 답변을 확장하기 위해. 그가 말했듯이, 실제 백업 필드를 반환하는 것은 완전히 안전하지는 않습니다. 사용자는 여전히 동적으로 캐스팅 할 수 있기 때문입니다. IEnumerable 다시 ArrayList.

원래 목록을 수정하지 않도록 이와 같은 내용을 작성합니다.

public IEnumerable MyList
{
    get
    {
         foreach (object o in mMyList)
             yield return o;
    }
}

그런 다음 다시, 나는 또한 일반 목록을 사용합니다 (IEnumerable<T>) 완전히 안전하다.

a ReadOnlyCollection.

return new ReadOnlyCollection<object>(mMyList).

당신은 또한 만들 수 있습니다 ReadOnlyCollection 필드이며 기본 목록의 변경 사항을 자동으로 반영합니다. 이것은 가장 효율적인 솔루션입니다.

mmylist에 한 가지 유형의 객체 만 포함되어 있다는 것을 알고 있다면 (예 : dateTime 이외의 경우) ReadOnlyCollection<DateTime> 추가 유형 안전을위한 (또는 다른 유형). C# 3을 사용하는 경우 간단히 쓸 수 있습니다.

return new ReadOnlyCollection<DateTime>(mMyList.OfType<DateTime>().ToArray())

그러나 이것은 기본 목록으로 자동 업데이트되지 않으며 효율성이 떨어집니다 (전체 목록을 복사 할 것입니다). 가장 좋은 방법은 mmylist를 일반으로 만드는 것입니다 List<T> (예 : a List<DateTime>)

리턴 값을 읽기 전용 컬렉션에 래핑해야합니다.

.NET v2.0에서 사용할 수 있습니다

    public ArrayList MyList { get; private set; }

부동산을 봉인 된 것으로 (또는 VB.NET에서는 불가능한)로 만들고 다음과 같이 읽기 만하면됩니다.

   public sealed readonly ArrayList MyList
   {
       get { return mMyList;}
   }

또한 후원 필드를 준비된 것으로 잊지 마십시오.

   private readonly ArrayList mMyList;

그러나 mmylist의 값을 초기화하려면이 예제에서와 같이 생성자에서만 초기화해야합니다.

public SampleClass()
{
   // Initialize mMyList
   mMyList = new ArrayList();
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top