【问题标题】:Guidelines for returning Generic Interface Collections返回通用接口集合的指南
【发布时间】:2012-03-07 23:33:01
【问题描述】:

我通常会尝试遵循一种方法,即让方法的参数尽可能通用,并根据需要返回通用类型,但我遇到了一个我不太清楚答案的问题。

我有一个控件,它在如下结构上运行:

IDictionary<string, IDictionary<string, IEnumerable<MyObject>>>

所以提供两个键,我们得到一个对象的集合。非常直接。

我有课

ReadOnlyDictionary<TKey, TValue> : IDictionary<TKey, TValue>

就是这样,一个只读字典,因此任何会改变字典的 IDictionary 方法都会抛出 NotSupportedException();

控件操作的字典来自 MyObjectRepository,它返回一个

ReadOnlyDictionary<string, ReadOnlyDictionary<string, ReadOnlyCollection<MyObject>>>

所以问题是,我是否应该将存储库上的返回类型更新为返回

IDictionary<string, IDictionary<string, IEnumerable<MyObject>>>

还是……?我认为更新方法以获取只读字典是不正确的,因为这是不必要的限制。

这似乎使返回类型不太清楚。此外,该接口将 ReadOnlyDictionary 定义为返回类型,因此实现类不能返回允许修改的字典。感觉就像接口返回一个应该只读的集合,那么返回类型应该反映这一点。通过指定泛型 IDictionary<...> 返回类型,使用该接口的方法可能会尝试修改字典以仅遇到 NotSupportedException。

感谢任何有关如何解决此问题的建议!

更新 事实证明,这里真正的问题在于 ReadOnlyCollection。它应该被 IEnumerable 取代,它简化了在各种返回类型之间转换的大部分工作。

请参阅 ReadOnlyCollection or IEnumerable for exposing member collections? 并注意 Jon Skeet 的回答。这就是我喜欢 SO 的原因 :)

【问题讨论】:

    标签: generics collections interface dictionary return-type


    【解决方案1】:

    我倾向于定义接口:DoubleKeyLookup&lt;out ValT&gt;,并由此派生DoubleKeyLookup&lt;in KeyT1, in KeyT2, out ValT&gt;。第一个将具有GetSequence(Object key1, Object key2);TryGetSequenceGetSequenceOrEmpty 之类的方法(前者将抛出未找到;第二个将返回null;第三个将返回Enumerable&lt;ValT&gt;.Empty)。第二个类似,但带有指定类型的“关键”参数。大多数消费者可能会使用第二个,但第一个可以在有人想要的情况下使用,例如查看特定的Animal 是否在所有键都是Cat 的字典中。

    【讨论】:

    • 我喜欢这个答案的灵活性,它似乎遵循 linq,我们有一个方法会抛出,一个返回 null,一个返回空。感谢您的想法
    【解决方案2】:

    我能想到的最简单、最人性化的方式是:

    由于 ReadOnlyDictionary 实现了 IDictionary 但在不受支持的操作上引发异常,我建议最简单且最易读的方法是返回实现 IReadOnlyDictionary 的 ReadOnlyDictionary。 IReadOnlyDictionary 将简单地从 IDictionary 派生,因为它们在功能上是等效的。

    然后,方法原型中的名称“IReadonlyDictionary”将向调用者指示更改字典的方法可能不起作用。

    希望这会有所帮助!

    【讨论】:

    • 我喜欢提供的两个答案,并且可能会将其用于更简单的项目。
    猜你喜欢
    • 2011-02-07
    • 1970-01-01
    • 1970-01-01
    • 2020-01-27
    • 2019-05-10
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多