我一直认为,当有一个公共API时,返回数组比列表更好,但现在似乎可以通过LINQ等在列表上使用所有这些函数。
这里是否更改了返回原语或对象集合的最佳实践?
例如:
Order[] GetOrders();
List<Order> GetOrders();
IEnumerable<Order> GetOrders();
IQueryable<Order> Get Orders();
发布于 2010-06-28 11:34:12
我认为最常用的类型是IEnumerable<T>
具有IEnumerable<T>
返回类型的
yield
关键字,这样就可以延迟枚举和执行您的方法。(例如,一个常见的抱怨是System.IO.Path.GetFiles()不返回数组,而是返回一个数组,这意味着当您调用该方法时,需要枚举所有项,而不管您是否需要它们。+你也有同样的缺点,在IEnumerable<T>
IEnumerable<T>
返回类型上工作的List<T>
)List<T>
和Array
实现的one.IEnumerable<T>
,因此很容易更改方法的实现,并且仍然支持以前的返回类型。发布于 2010-06-28 11:47:32
因为我通常只从属性/方法返回不可变(不可修改)的对象,所以这个答案假设您也想这样做。
不要忘记ReadOnlyCollection<T>
,它返回一个仍然可以通过索引访问的不可变集合。
如果您正在使用IEnumerable<T>
并将您的类型发布到无法控制的荒野中,请注意这一点:
class MyClass {
private List<int> _list;
public IEnumerable<int> Numbers {
get { return _list; }
}
}
因为用户可能会这样做,并弄乱类的内部状态:
var list = (List<int>)myClass.Numbers;
list.Add(123);
这将违反属性的只读意图。在这种情况下,你的getter应该是这样的:
public IEnumerable<int> Numbers {
get { return new ReadOnlyCollection<int>(_list); }
}
或者,您可以调用_list.ToReadOnly()
。我把它完整地写出来,以显示它的类型。
这将阻止任何人修改您的状态(除非他们使用反射,但这真的很难阻止,除非您构建像许多函数式编程语言中使用的那样的不可变集合,而这完全是另一回事)。
如果要返回只读集合,最好将成员声明为ReadOnlyCollection<T>
,这样某些操作的执行速度会更快(获取计数,通过索引访问项,复制到另一个集合)。
就我个人而言,我希望看到框架包含并使用这样的接口:
public interface IReadOnlyCollection<T> : IEnumerable<T>
{
T this[int index] { get; }
int Count { get; }
bool Contains(T item);
void CopyTo(T[] array, int arrayIndex);
int IndexOf(T item);
}
您可以在IEnumerable<T>
之上使用扩展方法获得所有这些函数,但它们的性能不是很好。
发布于 2010-06-28 11:34:39
是否希望集合是不可变的?IEnumerable<T>
可变的?IList<T>
你需要索引吗?IList<T>
通过列表或数组,API使用者拥有添加、删除、删除、清除等全部功能。
使用IEnumerable<T>
,API使用者得到一个“包”中的项,没有特定的顺序,没有索引,也没有修改集合的方法。
在某些有限的情况下,您可能希望返回IQueryable<T>
,但这些情况通常特定于零散地构建查询。
一般来说,我会默认使用IEnumerable<T>
。我可能会使用List<T>
作为支持字段,但只希望允许用户删除,例如,不允许删除、清除或其他任何操作,所以我声明了一个public void Add<T>(T item)
,它只是将该项添加到支持字段列表中。
https://stackoverflow.com/questions/3129889
复制相似问题