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# 无法在linq语句中重新分配值_C#_Linq - Fatal编程技术网

C# 无法在linq语句中重新分配值

C# 无法在linq语句中重新分配值,c#,linq,C#,Linq,我正在尝试将int类型列表中的所有数字平方。但是,当我运行代码时,列表似乎根本没有更改 public static List<int> SquareList(List<int> root) { root.ForEach(x => x = x*x); return root; } 以x_为单位的测试类 [Fact] public void testSqures() { var input = new List<int> { 1,

我正在尝试将int类型列表中的所有数字平方。但是,当我运行代码时,列表似乎根本没有更改

public static List<int> SquareList(List<int> root)
{
    root.ForEach(x => x = x*x);
    return root;
}
以x_为单位的测试类

[Fact]
public void testSqures()
{
    var input = new List<int> { 1, 2, 3 };
    var expected = new List<int> { 1, 4, 9 };
    var result = Square.SquareList(input);

    Assert.Equal(expected,result);
}
问题:foreach运算符是否不更改基础对象

我需要创建一个新列表吗?或者有没有一种方法可以将列表转换到位

将其更改为

return root.Select(x => x*x).ToList();
这不会改变现有列表,而是创建一个新列表并返回首选列表。如果确实要更新原始列表,请将签名更改为传入ref,然后更新指向新列表的指针

public static List<int> SquareList(ref List<int> root)
{
    root = root.Select(x => x*x).ToList();
    return root;
}
或者与for循环一起使用

public static List<int> SquareList(List<int> root)
{
    for(int i = 0; i < root.Count; i++)
        root[i] = root[i]*root[i];
    return root;
}

ForEach会迭代列表,如果引用类型类包含int,则可以更改该类型内的值,但不能重新分配列表中包含的指针。

如果要获取集合的新表示形式,请使用Select而不是ForEach。返回新对象而不是改变它是函数式编程的一种范例。LINQ有助于使用这个范例。

来自MSDN:

不支持修改操作委托主体中的基础集合,这会导致未定义的行为

您应该只使用常规for循环来完成这些事情,而不是使用LINQ或类似的函数语句

public static List<int> SquareList(List<int> root)
{
    for (int i = 0, n = root.Count; i < n; ++i)
        root[i] = root[i] * root[i];
    return root;
}

来自MSDN:不支持修改操作委托主体中的基础集合,这会导致未定义的行为。您正在使用值类型,无法在操作委托中更新值类型。您肯定需要创建一个新列表。您引用的文档与问题无关。警告是指对集合结构的修改,即删除或插入/添加元素,而不是简单地替换值。@PeterDuniho恕我直言,您是否有任何带有ValueType的官方文档或代码示例来证明您的观点?我认为您混淆了修改基础集合和修改基础集合引用的值这两个术语。如果您试图修改集合,则会抛出InvalidOperationException,消息集合已修改;枚举操作可能无法执行。。这与试图修改本身不属于集合的值类型是完全不同的问题。代码示例:列表值=新列表{0,1,2};values.ForEachi=>values[i]=i+1;,抛出异常。ForEach不应用于修改列表,这是正确的,但引用文档的特定部分是不正确的,因为它与OP的代码无关。@PeterDuniho您的代码示例支持我所说的。这里似乎没有人在谈论试图修改一个本身并不属于集合的值类型。List是一种引用类型,int是一种值类型,我们讨论的是在容器List引用类型中修改这个包含的int值类型。我对这个主题没有任何进一步的评论。OP正在用x*x替换存储在x中的值,该值传递给他的动作代理。这对原始集合没有影响,因此MSDN中的警告不适用。