2012-02-16 31 views
0

我通常会尝试遵循方法参数的方法尽可能通用,并根据需要返回泛型类型,并遇到问题,而答案对我来说不太清楚。返回通用接口集合的指导原则

我有一个结构类似操作的控制:

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

这样提供两个按键,我们得到对象的集合回来。非常直截了当。

我有一个类

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

这仅仅是,只读字典使得任何IDictionary的方法,其将改变字典抛出NotSupportedException异常();

上控制操作字典出来它返回一个

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

一个MyObjectRepository的所以现在的问题是,我应该更新我的仓库返回类型返回

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

或...?我认为更新该方法以只读字典作为不必要的限制是不正确的。

看来,这使得它不太清楚返回类型。另外,接口将ReadOnlyDictionary定义为返回类型,以便实现类不能返回允许修改的字典。它只是觉得如果接口正在返回一个只能读取的集合,那么返回类型应该反映它。通过指定泛型IDictionary < ...>返回类型,使用该接口的方法可能会尝试修改字典仅运行到NotSupportedException。

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

UPDATE 事实证明,这里真正的问题是ReadOnlyCollection。它只是应该由IEnumerable替换,它简化了大量在各种返回类型之间转换的工作。

请参阅ReadOnlyCollection or IEnumerable for exposing member collections?并注意Jon Skeet的回答。这就是为什么我爱SO :)

回答

1

我的倾向是定义接口:DoubleKeyLookup<out ValT>,并从中推导出来,DoubleKeyLookup<in KeyT1, in KeyT2, out ValT>。第一种方法有GetSequence(Object key1, Object key2);,TryGetSequenceGetSequenceOrEmpty(前者会丢失未找到;第二个将返回null;第三个将返回Enumerable<ValT>.Empty)。第二个类似,但具有指定类型的“关键”参数。大多数消费者可能会使用第二种,但是第一种可以用于例如想要例如看看某个特定的Animal是否在字典中,其中所有密钥都是Cat

+0

我喜欢这个答案的灵活性,它似乎遵循linq我们有一个方法将抛出,一个返回null,一个返回一个空。感谢这个想法 – MPavlak 2012-02-17 12:59:03

1

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

由于ReadOnlyDictionary实现IDictionary的<,>但不支持的操作抛出异常,我建议最简单的最可读的方式是返回ReadOnlyDictionary <,>实现IReadOnlyDictionary <,>代替。 IReadOnlyDictionary <,>将简单地从IDictionary <派生,>因为它们在功能上是等效的。

方法原型中的名称“IReadonlyDictionary”然后会向调用方指示修改字典的方法可能无效。

希望这会有所帮助!

+0

我喜欢这两个答案提供,并可能会用于更简单的项目。 – MPavlak 2012-02-17 12:57:40