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 =&gt; (g.ACode == Convert.ToInt16(a))) 是否实际上返回了 1 和 2 的行。此外,您使用的是什么版本的 Visual Studio,2013 年 foreach 循环中变量捕获的行为发生了变化 @Scott Chamberlain 它正在返回 1 和 2 的值,我使用的是 VS 2010 【参考方案1】:

据我了解,您想要做的是拥有所有 GeosACode。您可以这样做,而不是为每个 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 =&gt; (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不适用于每个循环[重复]的主要内容,如果未能解决你的问题,请参考以下文章

新行分隔符不适用于 group_concat 函数

GROUP_CONCAT 不适用于左连接

添加到 IEnumerable 的代码

数据结构:单向循环链表

数据结构:单向循环链表

yajra / laravel-datatables搜索不适用于laravel 5.4