Ienumerable concat不适用于每个循环[重复]
Posted
技术标签:
【中文标题】Ienumerable concat不适用于每个循环[重复]【英文标题】:Ienumerable concat not working in for each loop [duplicate] 【发布时间】:2017-01-10 16:29:26 【问题描述】:我正在尝试在 for each 循环中使用 IEnumerable 的 Concat
方法,但我无法使其正常工作。
IEnumerable<Geo> geos = null;
foreach (string a in values)
if (geos == null)
geos = entities.Geos.Where(g => (g.ACode == Convert.ToInt16(a)));
else
geos = geos.Concat(entities.Geos.Where(g => (g.ACode == Convert.ToInt16(a))));
它返回的只是值中最后一个“a”的值,以及值中存在的记录数。
所以如果我有 1,2,3 作为值,它只返回 3。我也需要 1,2 和 3 的值。
我哪里错了?
【问题讨论】:
我会检查entities.Geos.Where(g => (g.ACode == Convert.ToInt16(a)))
是否实际上返回了 1 和 2 的行。此外,您使用的是什么版本的 Visual Studio,2013 年 foreach 循环中变量捕获的行为发生了变化
@Scott Chamberlain 它正在返回 1 和 2 的值,我使用的是 VS 2010
【参考方案1】:
据我了解,您想要做的是拥有所有 Geos
和 ACode
。您可以这样做,而不是为每个 a
遍历 Geos
列表:
var intValues = values.Select(value => Convert.ToInt16(value));
var geos = entities.Geos.Where(g => intValues.Contains(g.ACode));
【讨论】:
【参考方案2】:您可能使用的是旧版本的 C#,在 C# 5(随 Visual Studio 2013 提供)中,它们更改了 foreach
的行为。在 C# 4 中,g => (g.ACode == Convert.ToInt16(a))
中的 a
在延迟评估时将是 foreach
的最后一个值,而在 C# 5 和更高版本中,它将始终是当前值。
要获得 C# 5 的行为,您只需要在 foreach 循环的范围内声明一个额外的变量并在捕获中使用它。
IEnumerable<Geo> geos = null;
foreach (string a in values)
string b = a;
if (geos == null)
geos = entities.Geos.Where(g => (g.ACode == Convert.ToInt16(b)));
else
geos = geos.Concat(entities.Geos.Where(g => (g.ACode == Convert.ToInt16(b))));
如果您对 C# 4 及以下更改的内容感到好奇,您的原始代码将被翻译成
IEnumerable<Geo> geos = null;
using(IEnumerator<string> enumerator = values.GetEnumerator())
string a;
while(enumerator.MoveNext())
a = enumerator.Current;
if (geos == null)
geos = entities.Geos.Where(g => (g.ACode == Convert.ToInt16(a)));
else
geos = geos.Concat(entities.Geos.Where(g => (g.ACode == Convert.ToInt16(a))));
在 C# 5 和更新版本中,它被翻译成
IEnumerable<Geo> geos = null;
using(IEnumerator<string> enumerator = values.GetEnumerator())
while(enumerator.MoveNext())
string a = enumerator.Current;
if (geos == null)
geos = entities.Geos.Where(g => (g.ACode == Convert.ToInt16(a)));
else
geos = geos.Concat(entities.Geos.Where(g => (g.ACode == Convert.ToInt16(a))));
通过在 C# 4 中执行 string b = a;
,我们重新创建了声明在 while 循环内的行为。
【讨论】:
感谢 Scott,添加该行有效。 非常感谢@Scott 的详细解释,这是我今天学到的新东西。以上是关于Ienumerable concat不适用于每个循环[重复]的主要内容,如果未能解决你的问题,请参考以下文章