【发布时间】:2017-08-30 06:58:55
【问题描述】:
我今天在为拉取请求进行更改时注意到了一些有趣的事情。以下是我的代码:
public List<MatColor> Colors { get; set; }
public List<Customer> Customers { get; set; }
public ProductViewModel()
{
this.Colors = new List<MatColor>();
this.Customers = new List<Customer>();
var products = this.LoadProductViewList();
this.LoadColorComboBox(products);
this.LoadCustomerComboBox(products);
}
public void LoadColorComboBox(IEnumerable<Product> products)
{
this.Colors.Clear();
this.Colors = products.Select(p => new MatColor()
{ Code = p.ColorCode, Description = p.ColorDescription })
.DistinctBy(p => m.Code).DistinctBy(p => p.Description).ToList();
}
private void LoadCustomerComboBox(IEnumerable<Product> products)
{
this.Customers.Clear();
this.Customers = products.Select(p => new Customer()
{ Name = p.CustomerName, Number = p.CustomerNumber })
.DistinctBy(p => p.Number).DistinctBy(p => p.Name).ToList();
}
这段代码做了我想做的一切。它成功地填充了Colors 和Customers 列表。我理解为什么它总是能成功填充Colors 列表。那是因为LoadColorComboBox(...) 首先被调用。
但是IEnumerable<T> 只能被枚举,ONCE,对吧?因此,一旦它在LoadColorComboBox(...) 中被枚举,它是如何成功重置并因此在LoadCustomerComboBox(...) 中再次枚举的?我已经检查了LoadProductViewList() 返回的底层类型——它调用了一个返回Task<IEnumerable<Product>> 的REST 服务。我的IEnumerable<Product> 是否以某种方式作为值传递?它不是原始的,所以我的印象是它是一个引用类型,因此,默认情况下会通过引用传入,这会导致第二种方法崩溃。谁能告诉我这里没有看到什么?
【问题讨论】:
-
IEnumerable<T>可以枚举任意多次。我不确定你从哪里得到它不可能的想法。 -
为什么一个 IEnumerable
只能被枚举一次。它只是可枚举集合最简化的接口之一。 List 也实现了 IEnumerable 并且可以无限次枚举。您可能会将枚举与延迟执行混淆。这大多发生一次。 -
@BjörnBoxstart 你所说的延迟执行只发生一次是什么意思?延迟执行只是意味着在需要之前不执行计算;如果您多次迭代延迟执行的序列,它将多次执行这些计算。
-
@BJ Myers -- 我正在研究答案,因为我不了解 IEnumerable
与其他类型的集合(如 IList )的所有更精细的工作方式。无论如何,尽管遗憾地问了这个问题,但我不确定我从哪里得到一个 IEnumerable 只能在没有某种类型的位置重置的情况下枚举一次的想法。 -
对我的问题的仇恨仍在继续,但这是我从哪里得到“你只能枚举一个 IEnumerable 一次”的想法,所以人们明白我的想法起源于哪里:stackoverflow.com/questions/8240844/…
标签: c# wpf ienumerable