返回通用接口集合的指南

发布于 2025-01-06 10:12:09 字数 1315 浏览 2 评论 0原文

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

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

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

因此,提供两个键,我们就可以获得对象的集合。非常简单。

我有一个类

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

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

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

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

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

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

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

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

任何有关如何解决此问题的建议都将受到赞赏!

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

请参阅 ReadOnlyCollection 或 IEnumerable 用于公开成员集合? 并注意 Jon Skeet 的回答。这就是为什么我这么喜欢:)

I typically try to follow a methodology of having arguments to methods be as generic as possible and return types as generic as necessary and have run into a problem to which the answer is not overly clear to me.

I have a control which operates on a structure like:

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

So that supplying two keys, we get a collection of objects back. Pretty straight forward.

I have a class

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

which is just that, a readonly dictionary so that any IDictionary methods which would alter the dictionary throw an NotSupportedException();

The dictionary on which the control operates comes out of a MyObjectRepository which returns a

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

So the question is, should I update the return type on my repository to return

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

or ...? I don't think it would be correct to update the method to take a readonly dictionary as that is unnecessarily limiting.

It seems that this makes it less clear about the return type. Also, the interface defines the ReadOnlyDictionary as the return type so that implementing classes cannot return dictionaries which would allow modification. It just feels like if the interface is returning a collection which should be read only, then the return type should reflect that. By specifying the generic IDictionary<...> return type, methods which use the interface may try to modify the dictionary only to run into a NotSupportedException.

Any suggestions on how to resolve this are appreciated!

UPDATE
As it turns out, the real issue here is with the ReadOnlyCollection. It simply should be replaced by IEnumerable and it simplifies much of the work converting between various return types.

See ReadOnlyCollection or IEnumerable for exposing member collections? and notice Jon Skeet's answer. This is why I love SO :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦旅人picnic 2025-01-13 10:12:09

我倾向于定义接口:DoubleKeyLookup,并从中派生出DoubleKeyLookup。第一个将具有诸如 GetSequence(Object key1, Object key2);TryGetSequenceGetSequenceOrEmpty 之类的方法(前者会抛出 not-found ;第二个将返回 null;第三个将返回 Enumerable.Empty)。第二个类似,但具有指定类型的“关键”参数。大多数消费者可能会使用第二个,但如果有人想查看特定的Animal是否在所有键都是Cat的字典中,则可以使用第一个。

My inclination would be to define interfaces: DoubleKeyLookup<out ValT>, and derived from that, DoubleKeyLookup<in KeyT1, in KeyT2, out ValT>. The first would have methods like GetSequence(Object key1, Object key2);, TryGetSequence, and GetSequenceOrEmpty (the former would throw on not-found; the second would return null; the third would return Enumerable<ValT>.Empty). The second would be similar, but with 'key' parameters of the specified types. Most consumers would probably use the second, but the first would be usable in case one wanted to e.g. see if a particular Animal was in a dictionary where all the keys were Cat.

神妖 2025-01-13 10:12:09

我能想到的最简单、最用户友好的方法是:

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

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

希望这有帮助!

The simplest and most user-friendly way I can think of is:

Since ReadOnlyDictionary implements IDictionary<,> but throws exceptions on unsupported operations, I would recommend that the simplest and most readable way be to return a ReadOnlyDictionary<,> that implements IReadOnlyDictionary<,> instead. IReadOnlyDictionary<,> would simply derive from IDictionary<,> since they're functionally equivalent.

The name "IReadonlyDictionary" in the method prototype would then indicate to the caller that methods that alter the dictionary may not work.

Hope this helps!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文