我通常会尝试遵循一种方法,让方法的参数尽可能通用,并根据需要将类型返回为通用类型,并遇到一个问题,答案对我来说并不过分清楚。
我有一个控件可以在以下结构上运行:
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&lt; ...&gt;返回类型,使用该接口的方法可能会尝试仅修改字典以运行NotSupportedException。
对于如何解决这个问题的任何建议表示赞赏!
更新 事实证明,这里真正的问题是ReadOnlyCollection。它应该被IEnumerable替换,它简化了在各种返回类型之间转换的大部分工作。
请参阅ReadOnlyCollection or IEnumerable for exposing member collections?并注意Jon Skeet的回答。这就是我爱SO的原因:)。
答案 0 :(得分:1)
我能想到的最简单,最人性化的方式是:
由于ReadOnlyDictionary实现了IDictionary&lt;,&gt;但是在不支持的操作上抛出异常,我建议最简单和最可读的方法是返回ReadOnlyDictionary&lt;,&gt;实现IReadOnlyDictionary&lt;,&gt;代替。 IReadOnlyDictionary&LT;,&GT;将简单地从IDictionary&lt;,&gt;派生因为它们在功能上是等价的。
方法原型中的名称“IReadonlyDictionary”然后会向调用者指示改变字典的方法可能不起作用。
希望这有帮助!
答案 1 :(得分:1)
我倾向于定义接口:DoubleKeyLookup<out ValT>
,并从中导出DoubleKeyLookup<in KeyT1, in KeyT2, out ValT>
。第一个会有GetSequence(Object key1, Object key2);
,TryGetSequence
和GetSequenceOrEmpty
之类的方法(前者会抛出未找到;第二个会返回null
;第三个会返回Enumerable<ValT>.Empty
1}})。第二个是类似的,但具有指定类型的“关键”参数。大多数消费者可能会使用第二种,但第一种消费者可以使用,例如查看特定Animal
是否在字典中,其中所有键都是Cat
。