我的代码充满了集合-我想这不是一件不寻常的事情。但是,各种集合类型的用法并不明显也不是琐碎的。通常,我想使用公开“最佳” API且语法噪音最少的类型。 (有关可比的问题,请参见Best practice when returning an array of values,Using list arrays - Best practices)。有一些指南建议在API 中使用哪种类型,但是在常规(非API)代码中,这是不切实际的。
例如:new ReadOnlyCollection<Tuple<string,int>>(
new List<Tuple<string,int>> {
Tuple.Create("abc",3),
Tuple.Create("def",37)
}
)
List
是一个非常常见的数据结构,但是以这种方式创建它们会涉及很多语法噪声-并且很容易变得更糟(例如字典)。事实证明,许多列表从未更改,或者至少从未扩展。当然ReadOnlyCollection
引入了更多的语法噪音,甚至没有传达我的意思。毕竟ReadOnlyCollection
可以包装一个变异集合。有时我在内部使用数组,然后返回IEnumerable
表示意图。但是这些方法大多数都具有非常低的信噪比。这对于理解代码至关重要。
对于不是公共(public)API的所有代码中的99%,没有必要遵循框架准则:但是,我仍然想要可理解的代码和能传达意图的类型。
那么,处理沼泽标准任务(使小型集合传递值)的最佳实践方法是什么? 是否应该在可能的情况下使用数组而不是List
?还有其他东西吗?传递如此小的收藏集的最佳方法-干净,可读,合理有效-是什么?特别是,对于尚未阅读此问题并且不想阅读大量API文档但仍然了解其意图的 future 维护者,代码应该是明显的。 最小化代码困惑也是非常重要的-因此ReadOnlyCollection
之类的东西充其量是可疑的。对于具有较小表面的主要API,罗types类型没有错,但作为大型代码库中的常规做法,这没有错。
在没有大量代码困惑(例如显式类型参数)的情况下传递值列表的最佳方法是什么,但仍然可以清楚地传达意图?
编辑:阐明这是关于编写简短的代码,而不是关于公共(public)API。
最佳答案
更新:
因此,严格来讲,这并不是新事物。但是这个问题使我相信go ahead and announce an open source project I've had in the works for a while(仍在进行中,但是里面还有一些有用的东西),其中包括IArray<T>
接口(interface)(以及实现方式,自然而然),我认为它完全可以捕获您想要的内容:索引,已读,仅,甚至协变(bonus!)接口(interface)。
一些好处:
ReadOnlyCollection<T>
这样的具体类型,因此不会将您束缚于特定的实现。 ReadOnlyCollection<T>
),所以它“确实是”只读的。 ArrayBase<T>
(也在库中)派生并覆盖this[int]
和Count
属性即可完成。 如果这对您来说很有希望,请随时使用check it out,让我知道您的想法。
对于您担心这种“语法噪声”的地方,我还是不太清楚100%:在您的代码中还是在调用代码中?
如果您在自己的封装代码中可以容忍某些“噪音”,那么我建议您包装一个
T[]
数组并暴露一个碰巧是IList<T>
的ReadOnlyCollection<T>
:class ThingsCollection
{
ReadOnlyCollection<Thing> _things;
public ThingsCollection()
{
Thing[] things = CreateThings();
_things = Array.AsReadOnly(things);
}
public IList<Thing> Things
{
get { return _things; }
}
protected virtual Thing[] CreateThings()
{
// Whatever you want, obviously.
return new Thing[0];
}
}
是的,您的一端会有些杂音,但这还不错。而且您公开的界面非常干净。
另一个选择是创建自己的接口(interface)something like
IArray<T>
,该接口(interface)包装T[]
并提供仅获取索引器。然后揭露那个。这基本上和公开T[]
一样干净,但是不会错误地传达可以通过索引设置项目的想法。关于c# - 最佳实践列表/数组/ReadOnlyCollection的创建(和用法),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4614749/