gpt4 book ai didi

c# - Where vs. foreach with if - 为什么会有不同的结果?

转载 作者:太空狗 更新时间:2023-10-29 20:06:57 26 4
gpt4 key购买 nike

这段代码

using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApplication
{
internal class Program
{
public static void Main()
{
var values = new[] {1, 2, 3, 3, 2, 1, 4};
var distinctValues = GetDistinctValuesUsingWhere(values);
Console.WriteLine("GetDistinctValuesUsingWhere No1: " + string.Join(",", distinctValues));
Console.WriteLine("GetDistinctValuesUsingWhere No2: " + string.Join(",", distinctValues));
distinctValues = GetDistinctValuesUsingForEach(values);
Console.WriteLine("GetDistinctValuesUsingForEach No1: " + string.Join(",", distinctValues));
Console.WriteLine("GetDistinctValuesUsingForEach No2: " + string.Join(",", distinctValues));
Console.ReadLine();
}

private static IEnumerable<T> GetDistinctValuesUsingWhere<T>(IEnumerable<T> items)
{
var set=new HashSet<T>();
return items.Where(i=> set.Add(i));
}

private static IEnumerable<T> GetDistinctValuesUsingForEach<T>(IEnumerable<T> items)
{
var set=new HashSet<T>();
foreach (var i in items)
{
if (set.Add(i))
yield return i;
}
}
}
}

结果如下:

GetDistinctValuesUsingWhere No1: 1,2,3,4

GetDistinctValuesUsingWhere No2:

GetDistinctValuesUsingForEach No1: 1,2,3,4

GetDistinctValuesUsingForEach No2: 1,2,3,4

我不明白为什么我在“GetDistinctValuesUsingWhere No2”行中没有得到任何值。

谁能给我解释一下?

UPDATE 在 Scott 回答后,我将示例更改为以下内容:

       private static IEnumerable<T> GetDistinctValuesUsingWhere2<T>(IEnumerable<T> items)
{
var set = new HashSet<T>();
var capturedVariables = new CapturedVariables<T> {set = set};

foreach (var i in items)
if (capturedVariables.set.Add(i))
yield return i;
//return Where2(items, capturedVariables);
}

private static IEnumerable<T> Where2<T>(IEnumerable<T> source, CapturedVariables<T> variables)
{
foreach (var i in source)
if (variables.set.Add(i))
yield return i;
}

private class CapturedVariables<T>
{
public HashSet<T> set;
}

这将导致输出 1,2,3,4 的两倍。

但是,如果我只是取消注释该行

return Where2(items, capturedVariables);

注释行

foreach (var i in items) if (capturedVariables.set.Add(i)) yield return i;

在方法 GetDistinctValuesUsingWhere2 中,我只会得到输出 1,2,3,4 一次。尽管删除的行和现在未注释的方法完全相同。

我还是不明白......

最佳答案

GetDistinctValuesUsingWhere No2 不返回任何结果的原因是变量捕获。

你的where方法更像是这个函数

    private static IEnumerable<T> GetDistinctValuesUsingWhere<T>(IEnumerable<T> items)
{
var set=new HashSet<T>();
var capturedVariables = new CapturedVariables {set = set}
return Where(items, capturedVariables);
}

IEnumerable<T> Where(IEnumerable<T> source, CapturedVariables variables)
{
foreach (var i in items)
{
if (variables.set.Add(i))
yield return i;
}

}

因此,这两种方法在幕后都是yield return,但 GetDistinctValuesUsingWhere 会为每次调用重用哈希集,其中 GetDistinctValuesUsingForEach 会在每次枚举时生成一个新的哈希集。

关于c# - Where vs. foreach with if - 为什么会有不同的结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45887501/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com