c# – IEnumerable现在比IReadOnlyList更加防水吗?
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了c# – IEnumerable现在比IReadOnlyList更加防水吗?,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2878字,纯文字阅读大概需要5分钟。
内容图文
![c# – IEnumerable现在比IReadOnlyList更加防水吗?](/upload/InfoBanner/zyjiaocheng/789/d0ef9fd5aede4c0ab12c6e210106ba80.jpg)
我读过这个问题:IEnumerable vs IReadonlyCollection vs ReadonlyCollection for exposing a list member和这个问题:ReadOnlyCollection or IEnumerable for exposing member collections?.我很有意思这些答案是几年前写的.
Jon Skeet的回答表明我应该使用IReadOnlyCollection而不是IEnumerable,因为我非常谨慎地阻止这样的代码:
ICollection<Order> evil = (ICollection<Order>)customer.Orders;
evil.Add(order3);
现在看下面的代码:
public class Customer
{
private readonly List<Order> _orders = new List<Order>();
public string FirstName { get; set; }
public string LastName { get; set; }
public IEnumerable<Order> Orders
{
get { foreach (var order in _orders) yield return order; }
}
internal void AddOrder(Order order)
{
_orders.Add(order);
}
public void AddOrders(IEnumerable<Order> orders)
{
this._orders.AddRange(orders);
}
}
我可以使用这样的代码:
Order order1 = new Order();
Order order2 = new Order();
Order order3 = new Order();
Customer customer = new Customer();
customer.FirstName = "Fred";
customer.LastName = "Bloggs";
customer.AddOrder(order1);
customer.AddOrder(order2);
和这样:
Customer customer2 = new Customer();
customer2.FirstName = "Average";
customer2.LastName = "Joe";
List<Order> orders = new List<Order>();
Order order4 = new Order();
Order order5 = new Order();
orders.Add(order4);
orders.Add(order5);
customer2.AddOrders(orders);
使用此代码有任何风险吗?我试图尽可能地保持水密,因为它是公共API的一部分.这比IReadOnlyCollection更加防水吗?效率低下吗?请注意,这是代码的最终版本,因此没有其他方案需要考虑.
我担心的是:
>公开IEnumerable而不是只读列表.
>使用列表私下保存订单.
我尽力遵循这里描述的建议:https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/guidelines-for-collections.
解决方法:
我只想说:
public IReadOnlyList<Order> Orders => _orders.AsReadOnly();
它将您的List包装成只读包装器,所以“邪恶”的代码如下:
ICollection<Order> evil = (ICollection<Order>)customer.Orders;
evil.Add(order3);
只会抛出一个例外,即colleciton是只读的.使用IEnumerable对这种情况具有性能和可用性含义,但没有提供太多好处(我会说).
例如,我想这是获得大量客户订单的常见操作.如果返回IEnumerable – 与IReadOnlyList相比,该操作的性能较差,对调用者来说不太方便.
较少的性能是因为使用IEnumerable获取订单计数的唯一方法是Count()LINQ方法,而这个方法,在你的yield return实现中,必须经过整个集合并计算那里有多少项.使用IReadOnlyList,Count属性只包含该信息.
不太方便,因为不鼓励使用单个可枚举的多个枚举,VS会警告用户你的api.假设你的api用户有这样的代码:
IEnumerable<Order> orders = customer2.Orders;
// just an example, there is actually no need to check for count
// before enumerating
if (orders.Count() > 0) {
foreach (var order in orders) {
}
}
在foreach行上,VS将警告他“可能的多个IEnumerable枚举”.调用者可以用IEnumerable做的合理的事情就是枚举它.一旦.因此,为了避免这种警告,他将不得不编写一些丑陋的代码,或者执行var orders = customer.Orders.ToList(),创建不必要的列表副本并使用它.
没有理由限制你的api用户,除非枚举一次是使用该api的唯一正确方法.
内容总结
以上是互联网集市为您收集整理的c# – IEnumerable现在比IReadOnlyList更加防水吗?全部内容,希望文章能够帮你解决c# – IEnumerable现在比IReadOnlyList更加防水吗?所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。