3

我认为以下代码段不起作用(数组项未修改)是否正确,因为数组是整数,它是值类型。

class Program
{
    public static void Main()
    {
        int[] ints = new int[] { 1,2 };

        Array.ForEach(ints, new Action<int>(AddTen));

        // ints is not modified
    }
    static void AddTen(int i)
    {
        i+=10;
    }
}

如果示例使用字符串数组,这同样适用,大概是因为字符串是不可变的。

我的问题是:-

有没有解决的办法?我无法更改回调方法的签名 - 例如通过添加 ref 关键字并且我不想用类包装值类型 - 这可以工作......

(当然,我可以简单地编写一个老式的 foreach 循环来做到这一点!)

4

4 回答 4

9

您只是在更改局部变量 - 而不是列表中的项目。为此,您需要ConvertAll创建一个新列表/数组:

    int[] ints = new int[] { 1,2 };

    int[] newArr = Array.ConvertAll<int,int>(ints, AddTen);

和:

static int AddTen(int i)
{
    return i+10;
}

这也可以用匿名方法编写:

int[] newArr = Array.ConvertAll<int,int>(ints,
    delegate (int i) { return i+ 10;});

或者在 C# 3.0 中作为 lambda:

int[] newArr = Array.ConvertAll(ints, i=>i+10);

除此之外......一个for循环:

for(int i = 0 ; i < arr.Length ; i++) {
    arr[i] = AddTen(arr[i]); // or more directly...
}

但无论如何,你将不得不你的方法中获得价值。除非你改变签名,否则你不能。

于 2009-02-18T14:10:10.183 回答
4

Array.ForEach() 方法不会让您实际修改它的成员。您可以使用 LINQ 来修改它,例如

ints = ints.Select(x => x +10 ).ToArray();
于 2009-02-18T14:10:24.440 回答
0

foreach 是唯一的方法,数组和列表中的值类型总是被复制,因此修改它们是行不通的,除非你将修改后的值存储回来。AddTen 方法没有这样做,它修改了自己的副本。

于 2009-02-18T14:11:31.083 回答
0

首先,修改您正在foreach处理的集合通常很危险。大多数集合都维护一个内部“版本标签”来跟踪更改,因此枚举器在尝试迭代修改后的集合时会抛出异常。

至于您的问题,您无法使用值类型和Array.ForEach. 使用foreachConvert做你想做的事。

于 2009-02-18T14:13:14.450 回答