문제

모든 객체를 만들고 있는 컬렉션 시설 내가 돌아와 앞에 그것을 할 수있는 가장 좋은 방법은?

  1. 공공 시설로는 getter 반환을 참조하여 개인 변수
  2. 명시적 get_ObjList 및 set_ObjList 는 방법을 반환하고 새로운 또는 복제 개체의 모든 시간
  3. 명시적 get_ObjList 는 반환합니다 IEnumerator 및 set_ObjList 는 소 IEnumerator

그것은 효과를 내는 경우에는 모음을 배열(즉,objList.론())대나요?

반환하는 경우 실제로 컬렉션에 대한 참조는 그래서 나쁜를 만들기 때문에 그 종속성,그 이유 반환 모든 속성을 참조하나요?언제든지 노출에는 자식 개체에 참조로 내부는 그 아이의 없이 변경 될 수 있습니다 부모가"아는 것"이지 않는 한 아이는 속성을 변경 이벤트를 사용합니다.이 위험한 메모리 누수가?

고,지 않는 옵션 2 및 3break serialization?이 catch22 또는 당신을 구현해야하고 사용자 지정 직렬화를 언제든지 당신은 컬렉션이 있습니까?

일반 readonlycollection 을 것 같아 좋은 타협은 일반적으로 사용합니다.그것을 감싸는 명령과에 대한 액세스를 제한합니다.어쩌면 이것은 메모리 누수 및 serialization.그러나 그것은 아직도 문제 열거

어쩌면 그냥 따라 다릅니다.지 않는 경우에는 컬렉션을 수정한 후 다만으로 노출에는 공공의 접근을 통해 개인 변수당#1.당신이 원하지 않는 경우 다른 프로그램의 컬렉션을 수정하려면 다음#2 및/또는#3 는 더 낫습니다.

에서 암시적인 문제는 왜 하나의 방법이 사용될 또 다른 어떤 파급 효과에서 보안,메모리,serialization,etc.?

도움이 되었습니까?

해결책

어떻게 당신은 노출 컬렉션을 전적으로 의존하는 방법에 대한 사용자가 의도하는 상호작용할 수 있습니다.

1) 는 경우 사용자가 항목을 추가하고 제거하는 개체에서의 수집,그때 간단한을 얻을만 컬렉션 호텔은 최고의(옵션#1 에서 원래 질문):

private readonly Collection<T> myCollection_ = new ...;
public Collection<T> MyCollection {
  get { return this.myCollection_; }
}

이 전략은 사용 Items 컬렉션에서 증상은 무엇이고 WPF ItemsControl 컨트롤는 사용자가 항목을 추가하고 삭제하며 그들이 원하 제어 표시됩니다.이러한 컨트롤 게시 실제 수집 및 콜백을 사용하거나 이벤트 리스너를 추적의 항목입니다.

WPF 또한 노출하는 몇 가지 설정 가능한 모음을 허용할 사용자를 표시하 모음의 항목들을 제어 등 ItemsSource 객실에 ItemsControl (option#3 에서 원래의 질문에).그러나,이것은 일반적으로 사용한 경우.


2) 는 경우 사용자가 사용될 데이터를 읽는 유체를 사용할 수 있습 readonly 컬렉션으로, Quibblesome 제안:

private readonly List<T> myPrivateCollection_ = new ...;
private ReadOnlyCollection<T> myPrivateCollectionView_;
public ReadOnlyCollection<T> MyCollection {
  get {
    if( this.myPrivateCollectionView_ == null ) { /* lazily initialize view */ }
    return this.myPrivateCollectionView_;
  }
}

Note ReadOnlyCollection<T> 라이브 뷰를 제공합의 기본 컬렉션,그래서 당신은 당신을 만들어야합 보기 한다.

는 경우 내부 컬렉션을 구현하지 않습 IList<T>, 는 경우,또는 당신에 대한 액세스를 제한하려면 고급 사용자 수 있습니 대신 랩 컬렉션에 대한 액세스를 통해 열정:

public IEnumerable<T> MyCollection {
  get {
    foreach( T item in this.myPrivateCollection_ )
      yield return item;
  }
}

이러한 접근은 단순한 구현에 대해 알아야 할 모든 정보를 제공하는 모든 구성원을 노출하지 않고 내부의 컬렉션입니다.그러나,그것을 필요로 않는 컬렉션을 유지 unmodfied 으로,BCL 컬렉션 클래스에서 예외가 발생할 경우를 열거하려고 하 컬렉션한 후에는 수정되었습니다.는 경우 기본 수집을 가능성이 높은 변경할 수 있습을 만들거나 빛 래퍼를 열거하는 컬렉션을 안전하게,또는 복사본을 반환의 컬렉션입니다.


3) 마지막으로,필요할 경우 노출이 아니라 배열이 더 높은 수준의 컬렉션은 다음,반드시 당해 이용자의 복사본을 배열 사용자를 방지하기 위해서 그것을 수정(옵션#2 에서 원하는 질문):

private T[] myArray_;
public T[] GetMyArray( ) {
  T[] copy = new T[this.myArray_.Length];
  this.myArray_.CopyTo( copy, 0 );
  return copy;
  // Note: if you are using LINQ, calling the 'ToArray( )' 
  //  extension method will create a copy for you.
}

를 노출하지 않아야 합본 배열을 제공,당신이 할 수 없을 말할 때 사용자가 수정할 수 있습니다.수정 할 수 있도록 배열할 수 있습니다 추가 해당 SetMyArray( T[] array ) 방법,사용 또는 사용자 정의 인덱:

public T this[int index] {
  get { return this.myArray_[index]; }
  set {
    // TODO: validate new value; raise change event; etc.
    this.myArray_[index] = value;
  }
}

(물론,을 구현함으로써 사용자 지정 인덱서,당신은 중복의 작업 BCL 클래스:)

다른 팁

나는 보통 이용,공개 게터를 반환하는 시스템입니다.컬렉션이 있습니다.개체 모델.Readonlycollection 를:

public ReadOnlyCollection<SomeClass> Collection
{
    get
    {
         return new ReadOnlyCollection<SomeClass>(myList);
    }
}

고 공중에 대한 방법 개체를 수정하 컬렉션입니다.

Clear();
Add(SomeClass class);

하드 디스크 드라이브가 되어 저장소에 대한 다른 사람들을 혼란으로 다른 노출 개인 변수로 당 방법#1 저장으로 쓰는 자신의 API,그러나 나는 부끄러워 하는 경향이에서 멀리하는 생산 코드입니다.

는 경우에 당신은 단순히고자 노출에서 컬렉션을를 들어,다음 사용하 get/set 개인 변수 회원처럼 보인다는 가장 현명한 솔루션을 나(신의 첫 번째 제안 옵션).

왜 당신이 사용하는 것이 좋 readonlycollection 을(T)타협?는 경우에 당신은 여전히 변화 알림 만들어 원래 포장 명령을 사용할 수도 있습 a ReadOnlyObservableCollection(T) 포장의 컬렉션입니다.는 것이 더 적은 타협의에서 당신의 시나리오?

I'm a java developer 그러나 내 생각에 이것은 같은 c#.

내가 노출시키지 마십시오 개인 컬렉션을 제공하기 때문에 다른 프로그램의 일부를 변경할 수 있습 그것이 없이 부모를 몰래도록,getter 방법을 배열을 반환합체의 컬렉션에서 설정 메소드 호출 clearAll() 수집을 통해 다음 addAll()

Readonlycollection 을 여전히 단점이 있는 소비자의 확신할 수 없어 원래의 컬렉션가 변경되지는 않 부적절한 시간에.대신 사용할 수 있는 불변의 컬렉션.필요하신 경우에는 변경을 수행한 다음 변경하는 대신 원본은 받는 수정된 복사본입니다.방법은 구현되는것은 경쟁과 성능의 변경 가능한 컬렉션이 있습니다.또는 더 나은 없는 경우 복사본에 여러 번을 번호를 만들의 서로 다른(호환되지 않)변경 이후에 각각 복사합니다.

내가 사용하는 것이 좋습 new IReadOnlyList<T>IReadOnlyCollection<T> 인터페이스 컬렉션을 노출(필요합니다.NET4.5).

예제:

public class AddressBook
{
    private readonly List<Contact> contacts;

    public AddressBook()
    {
        this.contacts = new List<Contact>();
    }

    public IReadOnlyList<Contact> Contacts { get { return contacts; } }

    public void AddContact(Contact contact)
    {
        contacts.Add(contact);
    }

    public void RemoveContact(Contact contact)
    {
        contacts.Remove(contact);
    }
}

는 경우는 것을 보장하기 위해 필요 컬렉션을 할 수 없 조작 외부에서는 다음을 고려 ReadOnlyCollection<T> 거나 새로운 변경할 수 없는 컬렉션이 있습니다.

인터페이스를 사용하여 IEnumerable<T> 노출 수 있습니다.이 인터페이스를 정의하지 않는다는 보장이 여러 열거 잘 수행합니다.는 경우페이한 쿼리를 나타냅니다 그리고 모든 열거 쿼리를 실행시 다시.개발자는 인스턴스페이 알고하지 않을 경우 나타내는 수집 또는 쿼리를 수행합니다.

에 대해 더 많은 이 항목에서 읽을 수 있습이 Wiki 페이지.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top