linq 变量自身的变化?

anauzrmj  于 2023-11-14  发布在  其他
关注(0)|答案(1)|浏览(100)

看看这个GIF -你能看到一个改变j值的语句吗?
https://imgur.com/a/tjDmstd
以下是我的代码,如果需要的话:

for (int j = 0; j < types[i].GenericParameters.Count(); j++)
{
    // typeDocs is XElement
    // types[i].GenericParameters is a collection of objects (classes) with properties Name and Description

    string value = FindElementValueByName(typeDocs, "typeparam",
        types[i].GenericParameters.ElementAt(j).Name);
    types[i].GenericParameters = types[i].GenericParameters.Select((p, index) =>
    {
        if (index == j) p.Description = value;
        return p;
    });
}

字符串
下面是FindElementValueByName方法:

private string FindElementValueByName(XElement root, string searchFor, string compareTo)
{
    return root.Elements(searchFor).FirstOrDefault(p =>
    {
        string? name = p.Attribute("name")?.Value;
        if (name == null) return false;
        return name == compareTo;
    })?.Value ?? string.Empty;
}


真正让我惊讶的是,j是一个结构体(int),因此当传递给一个方法或任何地方时都不应该改变!
FYI:我知道Select语句在这里并不是真正必要的。我尝试使用types[i].GenericParameters.ElementAt(j).Description = value;,但是**Description属性没有被设置**。在我当前的代码中,它仍然没有在Select之后设置。

0lvr5msh

0lvr5msh1#

你在传递给Select的lambda中捕获j,它有一个懒惰的计算。如果你使用代码分析器或ReSharper,你必须得到一些关于它的possible side effect的警告。
在你的记录中没有第二次迭代(可能是因为类型只有一个泛型参数,但我们看不到),所以当传递给Select的lambda被执行时,你已经离开了for,但到那时j已经有了最终值。
一个可能的修复程序,如果你强制立即评估Select附加一个.ToList()..ToArray()

相关问题