【问题标题】:Why isn't the change to a field in an IEnumerable executed?为什么不执行对 IEnumerable 中的字段的更改?
【发布时间】:2013-01-17 21:11:38
【问题描述】:

惊讶地发现以下调用似乎不记得对该字段所做的更改。

private void Foo(IEnumerable<Blopp> blopps)
{
  foreach (Blopp blopp in blopps)
    blopp.SomeField = PREFIX + blopp.SomeField;

  String test = blopps.First().SomeField;
}

test 变量在使用 LINQ to data 获取数组时缺少前缀。我需要评估 IEnumerable 并将其设为 List 以使对字段的更改得以维持。为什么会这样?我希望程序能够识别该字段稍后使用并对其进行评估。

private void Foo(IEnumerable<Blopp> _blopps)
{
  List<Blopp> blopps = _blopps.ToList();
  foreach (Blopp blopp in blopps)
    blopp.SomeField = PREFIX + blopp.SomeField;

  String test = blopps.First().SomeField;
}

【问题讨论】:

  • _bloppsIEnumerbale 是什么?将其设为列表可能会解决其他动态生成的IEnumerable
  • @SteveB 这是一个由 class 定义的类型。

标签: c#


【解决方案1】:

这取决于你传递给它的内容。如果它是一个懒惰评估的序列,那么每次您“查看”blopps,它都会重新评估输入。

如果您传入 List&lt;T&gt; 之类的内容,则序列每次都将包含相同的精确值,所以这很好。如果您传入一个未实现的查询,它将在您每次查看输入时执行该查询。是否返回对与先前评估相同的对象的引用将取决于它在做什么。

(如 cmets 中所述,在某些情况下,对一次评估返回的对象的更改甚至可能会完全改变查询的结果 - 对象可能会以这样的方式进行修改,从而使其与之前的过滤器不匹配查询。)

【讨论】:

  • 我假设他有一个查询,该查询过滤了他想要更改的字段,并且他在 foreach 中更改了该字段,这也更改了查询的结果。但是,这应该会减少每次评估序列的Count(),并且不会导致错误的结果。
  • @TimSchmelter:这是另一种可能性,是的。基本上所有类型的事情都取决于输入的确切性质。
  • 该死...是否建议执行 ToList 以防止出现这种情况?有没有更好的方法?
  • @KonradViltersten 这取决于你没有提供的太多信息,所以我们不能说。您是否真的需要再次访问该信息,或者您只是验证它是否已设置?在这种情况下,它可能按原样工作,您只是没有正确地看到它正在工作。您的更改是否被应用或忽略主要取决于IEnumerable 的来源。详细说明对于获得有意义的答案大有帮助。
  • @KonradViltersten 这不是IEnumerable 这很奇怪,而是实现。它可以通过多种方式实现,其中一些很容易,而另一些则难以理解(其中一些可以说是错误的)。由于您对它的实现方式一无所知,因此我们无法解决这个问题。
猜你喜欢
  • 2019-03-17
  • 2021-10-06
  • 1970-01-01
  • 1970-01-01
  • 2021-08-23
  • 1970-01-01
  • 2020-10-27
  • 1970-01-01
  • 2014-01-09
相关资源
最近更新 更多