2009-06-27 3 views
2

에 대한 대안 TimeSheetActivity 클래스에는 할당 모음이 있습니다. 같은 Allocation.EventDate에 대한콜렉션 조회; Dictionary

public class Allocation : ValueObject 
{ 
    public virtual StaffMember StaffMember { get; private set; } 
    public virtual TimeSheetActivity Activity { get; private set; } 
    public virtual DateTime EventDate { get ... } 
    public virtual TimeQuantity TimeSpent { get ... } 
} 

중복 할당이 허용되지 않습니다 할당은 다음과 같이 뭔가를 찾고,뿐만 아니라 도메인의 다른 개체에 의해 사용되는 값 개체입니다. 따라서 클라이언트가 액티비티에 대한 할당을 시도하면 동일한 Allocation.EventDate에 대한 콜렉션에 이미 할당이 있는지 확인합니다. 그렇지 않은 경우 새 할당이 컬렉션에 추가되지만 기존 할당이 새 할당으로 대체됩니다.

저는 현재 Allocation.EventDate를 키로 사용하여 컬렉션을 유지 관리하기 위해 사전을 사용하고 있습니다. 그것은 도메인에 대해 잘 작동하지만 키가 이미 가치의 일부라는 사실 자체가 '나쁜 냄새'가 아닌지 궁금하네요.

사전 값 외에는 아무 것도 유지할 이유가 없습니다. 왜냐하면 NHibernate를 사용하고 있기 때문에, 커스텀 타입을 작성해야 할 필요가 있을지도 모릅니다. 또한 다른 유형의 콜렉션을 사용해야한다는 단서인지 궁금합니다. (이것이 Allocation 클래스의 가상 속성에 대한 이유이기도합니다).

내가 생각하는 주요 대안은 전용 EqualityComparer를 사용하는 HashSet입니다.

당신은 어떻게 생각하십니까?

건배, Berryl

+0

나는 이것이 아주 오래된 질문이라는 것을 알고있다. 하지만 왜 누구도 연결된 목록을 제안한 이유가 궁금합니다. 결국 이것은 사전이 충돌하는 해시를 위해 내부적으로 사용하는 것입니다. 'Dictionary '가 중복 키를 가질 수없는 유일한 이유는 키를 찾을 때 반환 할 내용을 알 수 없기 때문입니다. (Btw. 연결 형식을 구조체로 만들면 성능이 크게 향상됩니다.) – Aidiakapi

답변

3

외부 비교자를 사용하여 HashSet<Allocation>을 수행하는 경우 사전에 값을 다시 입력하지 않고 날짜를 변경하지 않도록주의해야합니다. 이 문제는 어느 쪽이든 해결할 수 있지만 변경 가능성으로 인해 악화됩니다 (적어도 Dictionary<,>은 여전히 ​​자체 키와 값을 추적 할 수 있습니다). 값의 일부로 변경 가능한 값을 사용하면 다시 값을 볼 수 없습니다. ...

이전에 일정 시스템에서 작업했을 때 실제로는 SortedList<,>을 사용했습니다. 비슷하지만 유용하지만 일반적으로 데이터를 순서대로 원하고 데이터가 상당히 균일하면 2 진 검색을 허용합니다.

+0

SortedList에 대한 도움말 주셔서 감사. 건배 – Berryl

3

나는 키가 값의 일부가 반드시 문제가 있다는 사실을 생각하지 않습니다. 제 경험상 그것은 사전의 경우에 자주 사용됩니다. 적절한 equality 비교자를 사용하는 HashSet은 확실하게 작동 할 것입니다. 특정 객체 인 EventDate을 사용하지 않아도됩니다. 그게 잠재적으로 할 수있는 유용한 것 같습니다 ...

당신은 현재 다소 모호한 방식으로 걱정하고 있습니까? 아니면 이것이 당신을 물릴 수 있는지에 대해 구체적인 의구심을 갖고 있습니까?

+0

키 값에 대한 다소 모호한 우려를 실제로 확인하고 싶습니다. 진실은 사전이 훌륭하고 사용하기 쉽다고 말해진다. 방금 ​​책의 1 부를 끝 냈습니다. btw ... 너는 훌륭한 작가 야! – Berryl

2

표준 라이브러리를 사용하면 내가 아는 더 나은 해결책이 없습니다. 그러나, 나는 또한 이런 종류의 코드가 "나쁜 냄새"라고 느꼈지만 BCL의 컬렉션 클래스가 아니라 코드 때문입니다.

MS가 데이터 집합의 일부인 데이터 구조를 구현할 수 있기 때문에 Dictionaries 대신 일반 집합 <TKey, TData> where TData: IKeyed<TKey>을 생성하지 않은 이유를 모르겠습니다. KeyValuePair<TKey, TValue>: IKeyed<TKey>은이 인터페이스를 구현하는 도우미 구조 일 뿐이므로 지금 가지고있는 것과 동일한 사전 기능을 만들 수 있습니다.

또한 (작은 호언 장담을 계속하기 위해) 선언적 불변 유형의 개념을 추가하지 않고 가능한 일반 유형 제약 조건을 만들지 않은 이유가 궁금합니다. 이는 키가 해시 코드를 변경하지 않는지 확인하기 위해 허용 할 것이기 때문입니다. 런타임 (일부 변경 가능한 객체에 GetHashCode()Equals()을 구현하는 경우 현재 발생할 수 있음).

+0

변경 가능한 유형의 객체를 사전 키로 사용하는 것은 문제가되지 않습니다. 해당 형식으로 사용되는 객체 * 인스턴스 *는 사전에 저장되는 동안 변경 될 수있는 코드에 노출되지 않습니다. 변경할 수있는 형식의 불변 인스턴스를 유지 관리하는 데 Framework/컴파일러 지원을 사용하는 것이 유용 할 수 있지만 형식 시스템에 상당한 변경이 필요합니다. – supercat

+0

@supercat, 분명히 변경 가능한 객체가 처리되고 괜찮은 불변 객체로 사용되는 경우. 실제로 GetHashCode()를 사용하면 사전이나 해시 테이블을 만들 때와 같이 키로 사용 된 동일한 객체를 전달하더라도 키 객체의 변형으로 조회가 중단된다는 컴파일러에서 알 수 없습니다. 잘못된 양동이에. 보호 장치가 좋을 것입니다. – Lucero