Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.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# 选择后的foreach迭代_C#_Linq - Fatal编程技术网

C# 选择后的foreach迭代

C# 选择后的foreach迭代,c#,linq,C#,Linq,有人能解释这种行为吗 class Program { static void Main(string[] args) { var models = Enumerable.Range(0, 10).Select(x => new Model { Id = x.ToString() }); foreach (var model in models) { model.Data = $"{model.Id}

有人能解释这种行为吗

class Program
{
    static void Main(string[] args)
    {
        var models = Enumerable.Range(0, 10).Select(x => new Model { Id = x.ToString() });

        foreach (var model in models)
        {
            model.Data = $"{model.Id} Data bla";
        }

        foreach (var model in models)
        {
            Console.WriteLine($"{model.Id} | {model.Data}");
        }

        Console.ReadLine();
    }
}

public class Model
{
    public string Id { get; set; }
    public string Data { get; set; }
}
输出:

0|

一,|

二,|

但是,如果在选择之后调用ToList(),则输出将更改为:

0 | 0数据bla

1 | 1数据bla

2 | 2数据bla

我尝试在每个foreach块中放置一个断点,并调用

models.Any(x=>x.Equals(model))

但是总是返回false,而不使用ToList()调用

models
是一个序列,每次迭代时都会填充
Model
的新实例。也就是说,你每次都会得到一组新的实例


当您调用
ToList()
时,您将捕获一个迭代的副本和所有可以修改的实例

.Select()
在枚举之前不会具体化其结果。第一个
foreach
更改一组
newmodel{}
对象,第二个
foreach
处理一组全新的
newmodel{}
对象。
.ToList()
将它一劳永逸地具体化。但是foreach块本身不是通过模型枚举的吗?当然是这样——但是每个块都通过自己的一组模型枚举。第一个
foreach
也可能没有发生,因为结果从未被使用过。@StefanKovacs:如果没有
ToList
它就像你用
Enumerable.Range(0,10)替换
模型的每个实例一样。选择(x=>新模型{Id=x.ToString()})
,因为Select不会生成项目,它只提供允许生成它们的代码。当您迭代模型时,它每次都运行该代码来生成项目。实际上,我在模型对象中添加了一个新字段:
publicstringguid=System.Guid.NewGuid().ToString()并使用model.Id和model.Guid执行Console.WriteLine。第一个foreach中的模型与第二个foreach中的模型具有不同的guid谢谢@StefanKovacs仅供参考-您还可以查看
.GetHashCode()
,这是检查其是否为同一对象的更常见方法