source

읽기 전용 ObservableCollection 속성을 만들려면 어떻게 해야 합니까?

factcode 2023. 4. 19. 23:30
반응형

읽기 전용 ObservableCollection 속성을 만들려면 어떻게 해야 합니까?

(데이터베이스의) 객체 목록이 포함된 뷰 모델에 속성을 노출하려고 합니다.

이 컬렉션을 읽기 전용으로 만들어야 합니다.즉, 추가 및 삭제 등을 방지하고 싶습니다.하지만 포어치와 인덱서가 작동하도록 놔두세요.편집 가능한 컬렉션을 보유하고 있는 개인 필드를 선언하고 읽기 전용 공용 속성으로 참조합니다.다음과 같이

public ObservableCollection<foo> CollectionOfFoo { 
     get { 
         return _CollectionOfFoo;
     }
}

그러나 이 구문은 컬렉션에 대한 참조를 변경하는 것을 방해할 뿐입니다.추가/삭제 등을 방지하는 것은 아닙니다.

이를 실현하는 올바른 방법은 무엇일까요?

해결책은 다음과 같습니다.

public class Source
{
    Source()
    {
        m_collection = new ObservableCollection<int>();
        m_collectionReadOnly = new ReadOnlyObservableCollection<int>(m_collection);
    }
 
    public ReadOnlyObservableCollection<int> Items
    {
        get { return m_collectionReadOnly; }
    }
 
    readonly ObservableCollection<int> m_collection;
    readonly ReadOnlyObservableCollection<int> m_collectionReadOnly;
}

상세한 것에 대하여는, 「Read Only Observable Collection anti-pattern 」를 참조해 주세요.


[이전] 응답은 Read Only Foo에 액세스할 때마다 다른 Read Only Observable Collection을 반환합니다.이것은 낭비이며 미묘한 버그로 이어질 수 있습니다.

사용하는 것을 좋아하지 않습니다.ReadOnlyObservableCollection<T>실수/부정수업처럼 보이기 때문에 대신 계약 기반의 접근법을 선호합니다.

다음은 공변성을 가능하게 하는 사용법입니다.

public interface INotifyCollection<T> 
       : ICollection<T>, 
         INotifyCollectionChanged
{}

public interface IReadOnlyNotifyCollection<out T> 
       : IReadOnlyCollection<T>, 
         INotifyCollectionChanged
{}

public class NotifyCollection<T> 
       : ObservableCollection<T>, 
         INotifyCollection<T>, 
         IReadOnlyNotifyCollection<T>
{}

public class Program
{
    private static void Main(string[] args)
    {
        var full = new NotifyCollection<string>();
        var readOnlyAccess = (IReadOnlyCollection<string>) full;
        var readOnlyNotifyOfChange = (IReadOnlyNotifyCollection<string>) full;


        //Covarience
        var readOnlyListWithChanges = 
            new List<IReadOnlyNotifyCollection<object>>()
                {
                    new NotifyCollection<object>(),
                    new NotifyCollection<string>(),
                };
    }
}

속성 유형을 IENumerable로 변경할 수 있습니다.

public IEnumerable<foo> CollectionOfFoo { 
     get { 
         return _CollectionOfFoo;
     }
}

인덱서를 표시하는 표준 인터페이스가 있다고 생각하지 않습니다.필요한 경우 인터페이스를 작성하고 Observable Collection을 확장하여 구현할 수 있습니다.

public interface IIndexerCollection<T> : IEnumerable<T>
{
    T this[int i]
    {
        get;
    }
}

public class IndexCollection<T> : ObservableCollection<T>, IIndexerCollection<T>
{
}

또한 사용 중인 목록 클래스를 재정의하고 생성자 중 하나에 불변 플래그를 넣을 수 있습니다. 따라서 불변 플래그가 true로 설정된 상태에서 생성되었을 경우 해당 플래그가 추가/삭제되지 않습니다.

Read Only Observable Collection 사용< T >

public ReadOnlyObservableCollection<T> ReadOnlyFoo
{
    get { return new ReadOnlyObservableCollection<T> (_CollectionOfFoo); }
}

지적하신 바와 같이 Eric J의 답변은 매번 새로운 인스턴스를 반환하는 것이므로 사용하시기 바랍니다.

언급URL : https://stackoverflow.com/questions/1763696/how-can-i-make-a-read-only-observablecollection-property

반응형