gpt4 book ai didi

c# - 为什么 IEnumerable 成功枚举了两次而我没有做任何事情来重置它?

转载 作者:太空宇宙 更新时间:2023-11-03 18:03:14 24 4
gpt4 key购买 nike

今天,当我为拉取请求进行更改时,我注意到了一些有趣的事情。下面是我的代码:

    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();
}

这段代码完成了我想要的一切。它成功填充了 ColorsCustomers列出。我明白为什么它总是会成功填充 Colors列表。那是因为 LoadColorComboBox(...)首先被调用。

但是一个IEnumerable<T>只能被枚举,ONCE,对吧?所以一旦它在 LoadColorComboBox(...) 中被枚举,它是如何成功重置并因此在 LoadCustomerComboBox(...) 中再次枚举的? ?我已经检查了 LoadProductViewList() 返回的基础类型-- 它调用一个返回 Task<IEnumerable<Product>> 的 REST 服务.是我的IEnumerable<Product>以某种方式被传递为一个值?它不是原始类型,所以我的印象是它是一个引用类型,因此,默认情况下会通过引用传递,这会导致第二种方法失败。有人可以告诉我我在这里没有看到什么吗?

最佳答案

IEnumerable 是一个具有 GetEnumerator 方法的对象,它能够为您提供一个枚举器。通常人们会期望它能够为您提供任意数量的枚举器。一些特定的实现可能不支持它,但接口(interface)的契约是它应该能够为您提供您想要的数量。

至于它吐出的 IEnumerator 实例,它们确实在技术上有一个 Reset 方法,应该将其设置回序列的“开始”。然而在实践中,大多数实现往往不支持“重置”运算符,而只是在您调用该方法时抛出异常。

在您的情况下,您实际上并没有重置 IEnumerator 并尝试使用它两次获取序列的值(这是行不通的,因为没有来自 LINQ 的迭代器您用来创建序列的方法支持被重置)。您所做的只是获取多个不同的枚举器,这些 LINQ 方法都支持这些枚举器。

关于c# - 为什么 IEnumerable<T> 成功枚举了两次而我没有做任何事情来重置它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43218025/

24 4 0