我试图在 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 的值。
我哪里错了?
您可能使用的是旧版本的 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 循环内的行为。