Pergunta

classe A TimeSheetActivity tem uma coleção de alocações. Uma alocação é um objeto de valor que é usado por outros objetos no domínio, bem como, procurando algo como isto:

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 ... }
}

alocações duplicadas para o mesmo Allocation.EventDate não são permitidos. Assim, quando uma tentativa de cliente para fazer uma atribuição a uma atividade, é feita uma verificação para ver se já existe um Allocation na coleção para o mesmo Allocation.EventDate. Se não, então a nova alocação é adicionado à coleção, mas se assim for, a alocação existente é substituído por um novo.

Atualmente, estou usando um dicionário para manter a coleção, com o Allocation.EventDate como a chave. Ele funciona muito bem para o domínio, mas eu estou querendo saber se o fato de que a chave já é parte do valor em si não é um 'mau cheiro'.

Eu também não tenho nenhuma razão para persistir qualquer coisa, mas os valores de dicionário. Porque eu estou usando NHibernate, eu talvez precise escrever algum tipo personalizado fazer isso, e eu estou querendo saber se isso também é um indício de que eu deveria estar usando um tipo diferente de coleção. (Essa também é a razão para as propriedades virtuais na classe Allocation).

A principal alternativa Estou pensando seria um HashSet com um EqualityComparer dedicado.

O que você acha?

Cheers, Berryl

Foi útil?

Solução

Se você usar um comparador externo para fazer um HashSet<Allocation>, você teria que ser muito cuidado para não alterar a data sem re-introduzir o valor no dicionário. Você tem esse problema de qualquer forma, mas é agravada pela mutabilidade (pelo menos com Dictionary<,> ainda será capaz de controlar suas próprias chaves e valores). Com um valor mutável como parte da chave que você corre o risco de nunca mais ver o valor de novo ...

Quando eu trabalhei em sistemas de programação na SortedList<,> passado eu realmente usado para isso -. Semelhante, mas útil se você geralmente deseja que os dados em sequência, e permite busca binária se os dados é bastante uniforme

Outras dicas

Eu não acho que o fato de que a chave é parte do valor é necessariamente um problema. Na minha experiência que é bastante frequente o caso de dicionários. A HashSet com um comparador de igualdade apropriada certamente funcionar, desde que você nunca necessário para obter o objeto atual com um EventDate particular. Isso parece ser uma coisa útil para ser capaz de fazer, potencialmente ...

Você está atualmente apenas em causa de uma forma um tanto vaga, ou você tem uma suspeita concreta de como isso pode te morder?

Usando as bibliotecas padrão, não há solução melhor que eu saiba. No entanto, eu também senti este tipo de código para ser um "mau cheiro", mas é por causa das classes de coleção na BCL e não seu código.

Eu não sei por que MS não criou Sets<TKey, TData> where TData: IKeyed<TKey> genérico ou então ao invés de dicionários, porque isso permitiria implementação de tais estruturas de dados onde a chave é parte dos dados. O KeyValuePair<TKey, TValue>: IKeyed<TKey> seria apenas uma estrutura auxiliar de implementar essa interface e, assim, permitindo a criação de funcionalidade dicionário idêntica como temos agora.

Além disso (para continuar com o pequeno discurso) Eu me pergunto por que eles não adicionar a noção de declarativas tipos imutáveis ??e tornar esta uma possível genérico tipo de restrição, porque isso permitiria ter certeza de uma chave não muda sua hashcode durante a execução (o que pode acontecer actualmente se uma implementos GetHashCode() e Equals() em algum objeto mutável).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top