在我的代码中需要使用IEnumerable<>几次因此得到Resharper错误"可能的多个枚举IEnumerable".
示例代码:
public List<object> Foo(IEnumerable<object> objects)
{
if (objects == null || !objects.Any())
throw new ArgumentException();
var firstObject = objects.First();
var list = DoSomeThing(firstObject);
var secondList = DoSomeThingElse(objects);
list.AddRange(secondList);
return list;
}
Run Code Online (Sandbox Code Playgroud)
objects参数List,然后避免可能的多次枚举,但后来我没有得到我能处理的最高对象. IEnumerable到List在方法的开头: public List<object> Foo(IEnumerable<object> objects)
{
var objectList = objects.ToList();
// ...
}
Run Code Online (Sandbox Code Playgroud)
但这只是尴尬.
在这种情况下你会做什么?
我花了好几个小时思考暴露名单成员的主题.在与我的类似问题中,John Skeet给出了一个很好的答案.请随便看看.
ReadOnlyCollection或IEnumerable用于公开成员集合?
我通常非常偏执暴露列表,特别是如果您正在开发API.
我一直使用IEnumerable来公开列表,因为它非常安全,而且它提供了很大的灵活性.我在这里举一个例子
public class Activity
{
private readonly IList<WorkItem> workItems = new List<WorkItem>();
public string Name { get; set; }
public IEnumerable<WorkItem> WorkItems
{
get
{
return this.workItems;
}
}
public void AddWorkItem(WorkItem workItem)
{
this.workItems.Add(workItem);
}
}
Run Code Online (Sandbox Code Playgroud)
任何针对IEnumerable进行编码的人都非常安全.如果我后来决定使用有序列表或其他东西,它们的代码都没有中断,它仍然很好.这样做的缺点是IEnumerable可以被强制转换回这个类之外的列表.
出于这个原因,许多开发人员使用ReadOnlyCollection来公开成员.这是非常安全的,因为它永远不会被强制转换为列表.对我来说,我更喜欢IEnumerable,因为它提供了更大的灵活性,我是否想要实现与列表不同的东西.
我想出了一个我更喜欢的新想法.使用IReadOnlyCollection
public class Activity
{
private readonly IList<WorkItem> workItems = new List<WorkItem>();
public string Name { get; set; }
public IReadOnlyCollection<WorkItem> WorkItems
{
get
{
return new ReadOnlyCollection<WorkItem>(this.workItems);
}
}
public void AddWorkItem(WorkItem workItem)
{
this.workItems.Add(workItem);
} …Run Code Online (Sandbox Code Playgroud) 前段时间我发了一个关于参数的类似问题,它引用了一篇与这个问题更相关的文章,该文章提倡使用IReadOnlyCollection<T>over IEnumerable<T>。
最近,我一直在考虑回归的利弊
IEnumerable<T>。从好的方面来说,它与接口一样小,因此它使您作为方法作者比承诺更重的替代方案(如
IList<T>或(天堂禁止)数组)具有更大的灵活性。然而,正如我在上一篇文章中概述的那样,
IEnumerable<T>返回会诱使调用者违反Liskov 替换原则。这太容易让他们使用LINQ扩展方法,如Last()和Count(),其语义IEnumerable<T>不答应。需要的是一种更好的方法来锁定返回的集合,而不会使这种诱惑如此突出。(我想起了 Barney Fife 以艰难的方式学习这一课。)
输入
IReadOnlyCollection<T>, .NET 4.5 中的新内容。它只向IEnumerable<T>:Count属性添加了一个属性。通过承诺计数,您可以向呼叫者保证您IEnumerable<T>确实有终点站。然后他们可以Last()问心无愧地使用 LINQ 扩展方法。
但是,本文提倡ReadOnlyCollection<T>在您想要保护成员的情况下使用(和其他替代方法)。
所以,我和一个同事讨论过这个问题,我们有不同的意见。
他建议一个方法应该返回它所拥有的任何东西(例如 aList<T>或数组),如果该方法产生它并且调用者之后更改它不会对其他任何东西产生影响(即,它不是成员并且不属于任何生命周期大于方法调用)。
我的观点是ReadOnlyCollection<T>向调用者表明集合通常应保持原样。如果他们想改变它,那么他们有责任明确地将它转换为 aIList<T>或调用ToList它。
在微软的准则在特定的状态: …