値型または文字列の配列でArray.ForEachアクション述語を使ってC#
質問
の配列は値型である整数であるので、私は(配列項目が変更されていない)次のコードが動作しない考えに修正しています。
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ループを書くことができます!)
解決
あなたは、単にローカル変数を変更しています。これを行うには、新しいリスト/配列を作成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でます:
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...
}
しかし、一つの方法または別の、あなたは値を取得する必要があるとしているのうちのあなたの方法の。あなたが署名を変更しない限り、あなたがすることはできません。
他のヒント
Array.ForEach()メソッドを使用すると、実質的にそれのメンバーを変更させません。あなたは、このような
このようLINQを使用して、それを修正することができますints = ints.Select(x => x +10 ).ToArray();
foreachのが唯一の方法ですあなたが戻って変更された値を保存しない限り、配列やリストの値の型は、常にコピーされ、それらを変更することはそのため仕事に行くのではありません。 AddTen方法は、それはそれ自身のコピーを変更することをやっていません。
まずオフ、それはあなたがオーバーforeach
ingしているコレクションを変更することが一般的に危険です。ほとんどのコレクションは、それが変更され、コレクションを反復処理するためにattemtますときに、列挙子は例外がスローされます、変更を追跡するために内部の「バージョンタグ」を維持ます。
あなたの質問については、あなたは値の型とArray.ForEach
でそれを行うことができる方法はありません。あなたがやりたいforeach
またはConvert
を使用します。