퍼시스턴스 컬렉션을 구현 중입니다. 인자를 위해 함수형 언어에서 공통적으로 사용되는 스타일의 단일 연결 목록이라고합시다.퍼시스턴스 컬렉션과 표준 컬렉션 인터페이스
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); }
하지만 그 옵션에 대한 몇 가지 문제가 있습니다
- 이 사용자에게 혼동을 줄 수 것인가를? 누군가이 클래스를 사용하여 시나리오를 구상하고 Add() 메서드를 호출하면 예외가 발생하고 때때로 실행되지만 ICollection에 대해 일반적으로 예상되는대로 목록을 수정하지 않는다는 것을 알 수 있습니다. 참조가 사용 되는가?
에 이어
ICollection<T>
의 구현IsReadOnly
은 아마도 true를 반환해야합니다. 그러나 그것은 Add()가 클래스의 인스턴스와 함께 사용되는 다른 부분에서 암시되는 것과 충돌하는 것처럼 보일 것입니다.명시 적 구현 패턴을 다시 따르고 새로운 버전이
false
을 반환하고 명시 적 구현이true
을 반환하면서 Is (2)가 혼란스럽지 않게 해결 되었습니까? 아니면 그냥MyList<T>
의Add()
메서드가 돌연변이임을 암시하여 더 악화 되나요?아니면 기존 인터페이스를 사용하고 대신
IEnumerable<T>
에서 파생되는 별도의IPersistentCollection<T>
인터페이스를 만드는 것을 잊어 버리는 것이 좋습니다.
편집 나는 클래스의 이름을 변경하고, ICollection에를 사용하여 전환. 객체의 동작과 인터페이스와의 관계에 중점을두고 싶었습니다. 나는 방금 간단한 예로서 cons list를 보냈다. 죄수리스트를 구현할 때 덜 혼동스러운 이름을 시도하고 IList를 구현하지 말아야한다는 충고에 감사드립니다. IList는 빠른 랜덤 액세스를위한 인터페이스이기 때문에 구현해야하지만 다소 접선 문제입니다.
내가 의도 한 바는 프레임 워크에 구워진 읽기 전용 (또는 변경 불가능한) 컬렉션의 의미와 인터페이스에서 설명하는 것과 동일한 동작을 구현하는 영구 컬렉션 간의 긴장에 대해 다른 사람들이 생각하는 것입니다. , 돌연변이 부작용보다는 기능적으로 만 작용한다.
그것은 만들기 위해 나에게 더 나을
참 - 그러나 영구적이고 * (상대적으로) 빠른 랜덤 액세스를 갖는 구조는 어떨까요? 내가 물어 본 인터페이스 관련 질문에 초점을 맞추고 특정 클래스의 구현으로 인해 발생하는 문제를 무시하기를 바랍니다. –