c# 使用 Array.ForEach Action Predicate 和值类型或字符串数组
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/561170/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
c# using Array.ForEach Action Predicate with array of value type or string
提问by
Am I correct in thinking the following snippet does not work (the array items are not modified) becausethe array is of integer which is value type.
我认为以下代码段不起作用(数组项未修改)是否正确,因为数组是值类型的整数。
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;
}
}
The same would apply if the example used an array of string, presumably because string is immutable.
如果示例使用字符串数组,则同样适用,大概是因为字符串是不可变的。
The question I have is:-
我的问题是:-
Is there a way around this? I can't change the signature of the callback method - for instance by adding the ref keyword and I don't want to wrap the value type with a class - which would work...
有没有解决的办法?我无法更改回调方法的签名 - 例如通过添加 ref 关键字,我不想用类包装值类型 - 这会起作用......
(Of course, I could simply write an old fashioned foreach loop to do this!)
(当然,我可以简单地编写一个老式的 foreach 循环来做到这一点!)
采纳答案by Marc Gravell
You are simply changing the local variable - not the item in the list. To do this, you want ConvertAll
, which creates a new list/array:
您只是在更改局部变量 - 而不是列表中的项目。为此,您需要ConvertAll
创建一个新列表/数组:
int[] ints = new int[] { 1,2 };
int[] newArr = Array.ConvertAll<int,int>(ints, AddTen);
with:
和:
static int AddTen(int i)
{
return i+10;
}
This can also be written with an anonymous method:
这也可以用匿名方法编写:
int[] newArr = Array.ConvertAll<int,int>(ints,
delegate (int i) { return i+ 10;});
Or in C# 3.0 as a lambda:
或者在 C# 3.0 中作为 lambda:
int[] newArr = Array.ConvertAll(ints, i=>i+10);
Other than that... a for
loop:
除此之外……一个for
循环:
for(int i = 0 ; i < arr.Length ; i++) {
arr[i] = AddTen(arr[i]); // or more directly...
}
But one way or another, you are going to have to get a value outof your method. Unless you change the signature, you can't.
但无论如何,您将不得不从您的方法中获得价值。除非你改变签名,否则你不能。
回答by JaredPar
The Array.ForEach() method won't let you practically modify it's members. You can modify it by using LINQ such as this
Array.ForEach() 方法实际上不允许您修改它的成员。您可以使用 LINQ 修改它,例如
ints = ints.Select(x => x +10 ).ToArray();
回答by Frans Bouma
foreach is the only way, value types in arrays and lists are always copied and modifying them is therefore not going to work, unless you store the modified value back. The AddTen method isn't doing that, it modifies its own copy.
foreach 是唯一的方法,数组和列表中的值类型总是被复制,因此修改它们是行不通的,除非您将修改后的值存储回去。AddTen 方法没有这样做,它修改了自己的副本。
回答by Anton Gogolev
First off, it's generally dangerous to modify the collection you're foreach
ing over. Most collections maintain an internal "version tag" to keep track of changes, so enumerator will throw an exception when it will attemt to iterate over the modified collection.
首先,修改您正在foreach
结束的集合通常是危险的。大多数集合维护一个内部“版本标记”以跟踪更改,因此枚举器在尝试迭代修改后的集合时将抛出异常。
As for your question, there's no way you can do that with values types and Array.ForEach
. Use foreach
or Convert
to do what you want.
至于您的问题,您无法使用值类型和Array.ForEach
. 使用foreach
或Convert
做你想做的事。