2012-01-16 5 views
2

퍼시스턴스 컬렉션을 구현 중입니다. 인자를 위해 함수형 언어에서 공통적으로 사용되는 스타일의 단일 연결 목록이라고합시다.퍼시스턴스 컬렉션과 표준 컬렉션 인터페이스

class MyList<T> 
{ 
    public T Head { get; } 
    public MyList<T> Tail { get; } 

    // other various stuff 
    // . . . 
} 

하나 이상의 넓은 스트로크에서, ICollection<T>의 기대하는 모든 정상적인 동작을 구현할 수 있기 때문에이 클래스는, ICollection<T>을 구현하도록 자연 보인다. 그러나이 수업의 행동과 ICollection<T> 사이에는 많은 불일치가 있습니다. 예를 들어, 방법 Add()

void Add(T item); // ICollection<T> version 

의 서명은 또한 컬렉션을 변이합니다 부작용으로 수행되는 것으로 가정한다. 그러나 이것은 지속적인 데이터 구조이므로 Add()는 대신 새 목록을 만들어 반환해야합니다.

MyList<T> Add(T item); // what we really want 

은 이것이 바로 우리가 원하는 버전을 만드는 것입니다 해결, 또한 인터페이스에 정의 된 버전의 비 기능적 명시 적 구현을 ​​생성하는 가장 좋은 방법을 보인다.

void ICollection<T>.Add(T item) { throw new NotSupportedException(); } 
public MyList<T> Add(T item) { return new MyList<T>(item, this); } 

하지만 그 옵션에 대한 몇 가지 문제가 있습니다

  1. 이 사용자에게 혼동을 줄 수 것인가를? 누군가이 클래스를 사용하여 시나리오를 구상하고 Add() 메서드를 호출하면 예외가 발생하고 때때로 실행되지만 ICollection에 대해 일반적으로 예상되는대로 목록을 수정하지 않는다는 것을 알 수 있습니다. 참조가 사용 되는가?

  2. 에 이어 ICollection<T>의 구현 IsReadOnly은 아마도 true를 반환해야합니다. 그러나 그것은 Add()가 클래스의 인스턴스와 함께 사용되는 다른 부분에서 암시되는 것과 충돌하는 것처럼 보일 것입니다.

  3. 명시 적 구현 패턴을 다시 따르고 새로운 버전이 false을 반환하고 명시 적 구현이 true을 반환하면서 Is (2)가 혼란스럽지 않게 해결 되었습니까? 아니면 그냥 MyList<T>Add() 메서드가 돌연변이임을 암시하여 더 악화 되나요?

  4. 아니면 기존 인터페이스를 사용하고 대신 IEnumerable<T>에서 파생되는 별도의 IPersistentCollection<T> 인터페이스를 만드는 것을 잊어 버리는 것이 좋습니다.

편집 나는 클래스의 이름을 변경하고, ICollection에를 사용하여 전환. 객체의 동작과 인터페이스와의 관계에 중점을두고 싶었습니다. 나는 방금 간단한 예로서 cons list를 보냈다. 죄수리스트를 구현할 때 덜 혼동스러운 이름을 시도하고 IList를 구현하지 말아야한다는 충고에 감사드립니다. IList는 빠른 랜덤 액세스를위한 인터페이스이기 때문에 구현해야하지만 다소 접선 문제입니다.

내가 의도 한 바는 프레임 워크에 구워진 읽기 전용 (또는 변경 불가능한) 컬렉션의 의미와 인터페이스에서 설명하는 것과 동일한 동작을 구현하는 영구 컬렉션 간의 긴장에 대해 다른 사람들이 생각하는 것입니다. , 돌연변이 부작용보다는 기능적으로 만 작용한다.

그것은 만들기 위해 나에게 더 나을

답변

5

IList<T>을 구현하는 데 혼란을 겪게됩니까?

예. IList<T>의 구현이 던져지는 상황이 있지만 (예 : 목록의 크기를 조정하려고 시도했지만 배열이 배열 인 경우) IList<T>을 가지면 혼란 스럽습니다. 에는 빠른 임의 액세스가 없었습니다.

IPersistentList<T>을 새로 구현해야합니까?

누구나 사용할 것인지 여부에 따라 다릅니다. 당신의 계급의 소비자는 선택할 수있는 IPL<T>의 6 개의 다른 구현을 가질 것 같습니까? 단 하나의 클래스에 의해 구현 된 인터페이스를 만드는 데 아무런 의미가 없다. 그냥 수업을 사용하세요. 그 ItemsSource가 IList<T> 대신의 IEnumerable<T> 경우

WPF의 ItemsControl에 더 나은 성능을 얻을 수 있습니다.

그러나 영구 링크 된 목록에는 빠른 임의 액세스가 허용되지 않습니다.

+0

참 - 그러나 영구적이고 * (상대적으로) 빠른 랜덤 액세스를 갖는 구조는 어떨까요? 내가 물어 본 인터페이스 관련 질문에 초점을 맞추고 특정 클래스의 구현으로 인해 발생하는 문제를 무시하기를 바랍니다. –

3

새로운 IPersistentList<T> 인터페이스를하기 때문에 ("지속성은"데이터가 어딘가 저장됩니다처럼. 나에게 소리 때문에 또는 IImmutableList<T>), 정말, 무슨하는 것은 IList<T> 기대되는 것보다 다른 행동이다 . IList<T>을 구현하는 클래스는 변경할 수있는 IMHO 여야합니다.

물론 프레임 워크의 일부이기 때문에 클래스 이름 List<T>을 사용하지 않는 것이 좋습니다.

+0

불변성은'IsReadOnly' 속성이 있습니다. 문서는 읽기 전용 IList 에서 뮤 테이터가 호출 될 때 일어날 일을 정의하고'ReadOnlyCollection '. –

+0

@Sean U : itsme86에 동의합니다. IList 및 기타 잘 알려진 컬렉션 인터페이스를 구현하려면 여전히 필요한 멤버를 추가 할 수 있지만 질문에 윤곽을 그리면 돌연변이 메서드가 호출 될 때 예외를 throw해야합니다. –

관련 문제