Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/264.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么c Linq在包含列表的列表中使用引用而不是值_C#_Linq_List - Fatal编程技术网

C# 为什么c Linq在包含列表的列表中使用引用而不是值

C# 为什么c Linq在包含列表的列表中使用引用而不是值,c#,linq,list,C#,Linq,List,我对这个简单的代码有问题,我不明白为什么c会这样 问题似乎是c在列表中使用列表时使用Linq表达式引用而不是值 在数字循环中,我根据列表选择数字,它们都存在,因此所有数字都应添加到列表{1,2,3} 当您看到控制台的输出时,行为正常,它在数字循环中显示{1,2,3} 问题在列表的循环中,在这里,Linq似乎只将最后一个数字添加到列表中,以便输出{3,3,3} 我知道我不需要在列表中列出int,但这只是为了证明一点,这很奇怪,这是一个已知的bug吗 编辑:在5.0之前的c语言中,它似乎就是这样工作

我对这个简单的代码有问题,我不明白为什么c会这样

问题似乎是c在列表中使用列表时使用Linq表达式引用而不是值

在数字循环中,我根据列表选择数字,它们都存在,因此所有数字都应添加到列表{1,2,3}

当您看到控制台的输出时,行为正常,它在数字循环中显示{1,2,3}

问题在列表的循环中,在这里,Linq似乎只将最后一个数字添加到列表中,以便输出{3,3,3}

我知道我不需要在列表中列出int,但这只是为了证明一点,这很奇怪,这是一个已知的bug吗

编辑:在5.0之前的c语言中,它似乎就是这样工作的。 在C 5.0 VS2012+编译器中,此行为已修改为我所期望的

static void Main()
{
    var list = new List<IEnumerable<int>>();
    var numbers = new[] {1, 2, 3};
    var numbers2 = new[] {1, 2, 3};

    foreach (var number in numbers)
    {
        var result = from s in numbers2
                     where s == number
                     select s;

        Console.WriteLine(result.First()); // outputs {1,2,3}
        list.Add(result);
    }

    foreach (var num in list)
    {
        Console.WriteLine(num.First()); // outputs {3,3,3}
    }
}
输出

一, 2. 3. 3. 3. 三,

这个

没有达到你的期望。它不添加数字列表。它添加了一个查询。查询是按需执行的。因为,在最终的输出循环number=3中,所有三个查询都返回3

如果要添加列表,请通过将ToList追加到列表中,强制立即执行查询:


是的,它是已知的。我相信它在C5中是固定的

您可以在foreach中声明一个值,然后在Console.WriteLine中使用该值来停止它,只需使用num的结束值

请参阅此以获得更清晰的解释。
执行查询时,数字==3

这是因为第一个foreach循环已经执行,最后一次分配给number的是infact 3

必要时延迟执行LINQ查询,例如在调用ToList时

这不是一个奇怪的结果,这就是它的本意


顺便说一句,在C 5.0 VS2012+编译器中,此行为已被修改为您期望的行为。

linq表达式仅在需要其结果时才执行

所以

将在需要结果值时执行。但是,如果希望立即计算表达式,则需要从表达式中获取结果并创建一个对象

如果您想查看正确的流,那么在numbers2…中的from行上设置一个断点。。。。看看它什么时候被击中


希望能有所帮助……

我得到的结果是123@Teejay顺便说一句,在C 5.0 VS2012+编译器中,此行为已修改为您所期望的。看起来这在C5中是固定的。0@weston好吧,它似乎只在C5中固定,所以在此之前你可以看到这种情况发生。@hjgraca我已经尝试了3.5、4和4.5,正如你所期望的1,2,3,1,2,3VS2010它按你所说的做,VS2012它按1,2,3,1,2,3做。所以与C版本无关,但与编译器有关。你每天都会学到一些新东西。是的,这正是我不明白的,为什么在执行查询的最后,它只返回{3,3,3}而不是{1,2,3}?因为,在最后,数字=3。因此,其中s==number的查询只在3上匹配。声明查询时,不会烘焙number的当前值。相反:每次执行查询时,它都会检查number的当前值。如果我执行list.Addresult.ToList,则您完全正确;看起来查询已经执行,结果还可以。但这绝对是一种奇怪的行为…@hjgraca你认为这很奇怪,因为你可能不习惯Linq的延迟执行特性。换句话说,linq查询在必要时才会执行。酷,在C5.0中它似乎是固定的。谢谢你看我对@user2025312关于固定词的回答的评论。我会说“修改”而不是“固定”。他们认为这可能会误导一些程序员,但我认为旧的行为是他们的本意,也可以为代码添加一些强大的工具。@Teejay:旧的行为的存在是因为C 1.0编译器的设计决定,将循环变量的声明置于循环之外。当时,没有lambdas或LINQ,因此也没有什么不同。即使是C开发人员自己也普遍认为这是一个错误,例如…@Heinzi是的,我很了解这篇博文。如果你读了它,你可以读到[…]有一些很好的理由不做这个改变[…],其中有4个理由,所以我的观点可能不是那么愚蠢。@Heinzi这是我最喜欢的:它会使foreach语义与for语义不一致
list.Add(result);
list.Add(result.ToList());
var result = from s in numbers2
where s == number
select s;
var result = (from s in numbers2
where s == number
select s).ToList();