Question

Une classe TimeSheetActivity possède une collection d’allocations. Une allocation est un objet de valeur utilisé par d'autres objets du domaine, qui ressemble à ceci:

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

Les allocations en double pour la même Allocation.EventDate ne sont pas autorisées. Ainsi, lorsqu'un client tente d'affecter une activité à une activité, une vérification est effectuée pour voir s'il existe déjà une allocation dans la collection pour la même allocation.EventDate. Sinon, la nouvelle allocation est ajoutée à la collection, mais si c'est le cas, l'allocation existante est remplacée par la nouvelle.

J'utilise actuellement un dictionnaire pour gérer la collection, avec la clé Allocation.EventDate. Cela fonctionne bien pour le domaine, mais je me demande si le fait que la clé fasse déjà partie de la valeur ne soit pas en soi une "mauvaise odeur".

Je n'ai également aucune raison de persister autre que les valeurs du dictionnaire. Parce que j'utilise NHibernate, il se peut que je doive écrire un type personnalisé pour le faire, et je me demande si c'est aussi un indice sur le fait que je devrais utiliser un type de collection différent. (C’est aussi la raison des propriétés virtuelles dans la classe Allocation).

La principale alternative à laquelle je pense serait un HashSet avec un EqualityComparer dédié.

Qu'en pensez-vous?

Salut, Berryl

Était-ce utile?

La solution

Si vous utilisez un comparateur externe pour effectuer un HashSet<Allocation>, vous devez faire très attention de ne pas changer la date sans ressaisir la valeur dans le dictionnaire. Vous avez ce problème dans les deux cas, mais il est exacerbé par la mutabilité (au moins avec Dictionary<,> il sera toujours capable de suivre ses propres clés et valeurs). Si vous incluez une valeur modifiable dans la clé, vous risquez de ne plus jamais voir la valeur ...

Lorsque j’ai travaillé sur des systèmes de planification par le passé, j’ai utilisé SortedList<,> pour cela - similaire, mais utile si vous voulez généralement les données en séquence et permet la recherche binaire si les données sont assez uniformes.

Autres conseils

Je ne pense pas que le fait que la clé fasse partie de la valeur pose nécessairement un problème. D'après mon expérience, c'est souvent le cas pour les dictionnaires. Un HashSet avec un comparateur d’égalité approprié fonctionnerait certainement, tant que vous n’auriez jamais eu besoin d’obtenir l’objet actuel avec un EventDate particulier. Cela semble être une chose utile à faire, potentiellement ...

Êtes-vous actuellement préoccupé d'une manière quelque peu vague, ou avez-vous un soupçon concret quant à la manière dont cela pourrait vous mordre?

À l’aide des bibliothèques standard, il n’ya pas de meilleure solution à ma connaissance. Cependant, j'estimais aussi que ce genre de code était une & "Mauvaise odeur &"; Mais c'est à cause des classes de collection dans la BCL et non de votre code.

Je ne sais pas pourquoi MS n'a pas créé d'ensembles génériques <TKey, TData> where TData: IKeyed<TKey> ou plutôt à la place de dictionnaires, car cela permettrait d'implémenter de telles structures de données dans lesquelles la clé fait partie des données. La KeyValuePair<TKey, TValue>: IKeyed<TKey> serait simplement une structure d'assistance implémentant cette interface et permettant ainsi de créer une fonctionnalité de dictionnaire identique à celle que nous avons maintenant.

Aussi (pour continuer avec le petit discours), je me demande pourquoi ils n’ont pas ajouté la notion de types immuables déclaratifs et en ont fait une contrainte de type générique, car cela permettrait de s’assurer qu’une clé ne change pas son hashcode pendant l’exécution (ce qui peut arriver actuellement si on implémente GetHashCode() et Equals() sur un objet mutable).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top