2

TimeSheetActivity 类具有分配的集合。分配是一个值对象,也被域中的其他对象使用,看起来像这样:

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 的 Allocation。如果不是,则将新的分配添加到集合中,但如果是,则将现有的分配替换为新的分配。

我目前正在使用 Dictionary 来维护集合,并以 Allocation.EventDate 作为键。它适用于域,但我想知道密钥已经是值的一部分这一事实本身是否不是“难闻的气味”。

除了字典值之外,我也没有理由坚持任何东西。因为我使用的是 NHibernate,所以我可能需要编写一些自定义类型来做到这一点,我想知道这是否也是我应该使用不同类型的集合的线索。(这也是分配类中的虚拟属性的原因)。

我正在考虑的主要替代方案是带有专用 EqualityComparer 的 HashSet。

你怎么看?

干杯,贝里尔

4

3 回答 3

3

我不认为关键是价值的一部分这一事实一定是一个问题。根据我的经验,字典经常出现这种情况。HashSet只要您永远不需要使用特定的EventDate. 这似乎是一件很有用的事情,可能......

您目前是否只是以某种模糊的方式担心,或者您对这可能会如何咬您有具体的怀疑?

于 2009-06-27T22:00:02.340 回答
3

如果您使用外部比较器执行 a HashSet<Allocation>,则必须非常小心,不要在不重新键入字典中的值的情况下更改日期。无论哪种方式,您都会遇到这个问题,但可变性会加剧它(至少Dictionary<,>它仍然能够跟踪自己的键和值)。使用可变值作为键的一部分,您可能再也看不到该值...

当我过去在调度系统上工作时,我实际上已经用于SortedList<,>此 - 类似,但如果您通常希望数据按顺序排列,并且如果数据相当统一,则允许二进制搜索。

于 2009-06-27T22:01:04.833 回答
2

使用标准库,我知道没有更好的解决方案。但是,我也觉得这种代码是一种“难闻的气味”,但这是因为 BCL 中的集合类而不是您的代码。

我不知道为什么 MS 没有创建通用集合<TKey, TData> where TData: IKeyed<TKey>而不是字典,因为这将允许实现这样的数据结构,其中键是数据的一部分。这KeyValuePair<TKey, TValue>: IKeyed<TKey>将只是一个实现此接口的辅助结构,因此允许创建与我们现在拥有的相同的字典功能。

另外(继续小吐槽)我想知道为什么他们没有添加声明性不可变类型的概念并使其成为可能的泛型类型约束,因为这将允许确保键在运行时不会更改其哈希码(这可以如果一个人实现GetHashCode()并且Equals()在某个可变对象上,则当前发生)。

于 2009-06-27T23:16:19.160 回答