2022/8/19
C#にJavascriptのforEachっぽい拡張メソッドを実装する
C#で配列をループする時は基本的にはfor文かforeach文を使うのですがJavascriptのforEachメソッドに慣れた身としてはあれを使いたくて発狂する事があります。 例えばこんな時です
for文の場合
float[] audioSourceVolume = new float[] { 1.0f, 0.7f, 0.3f };
for (int i = 0; i < audioSourceVolume.Length; i++) {
Debug.Log($"ch{i}のボリュームは{audioSourceVolume[i]}");
}
//結果
//ch0のボリュームは1
//ch1のボリュームは0.7
//ch2のボリュームは0.3
こういう用途には冗長で可読性もよくない気がします。
foreach文の場合
float[] audioSourceVolume = new float[] { 1.0f, 0.7f, 0.3f };
int i = 0;
foreach (var item in audioSourceVolume) {
Debug.Log($"ch{i}のボリュームは{item}");
i++;
}
//結果
//ch0のボリュームは1
//ch1のボリュームは0.7
//ch2のボリュームは0.3
こっちは処理自体はすっきり書けていいんですが、foreach文はindexが使えないので別途index用の変数を宣言する等しないとなりません。 Array.ForEachやLinqを使ってもやっぱりちょっと長くなっちゃいます。 これがJavascriptのforEachメソッドだとこうなります。
JavascriptのforEachメソッドの場合
const audioSourceVolume = [ 1.0, 0.7, 0.3 ];
audioSourceVolume.forEach((e, i) => { console.log(`ch${i}のボリュームは${e}`); });
//結果
//ch0のボリュームは1
//ch1のボリュームは0.7
//ch2のボリュームは0.3
一行で書けます。 長い変数名の繰り返しやindexの加算処理を省けて可読性も高いです。 これをC#で使えるようにしたいと思います。
JavascriptのforEachっぽい拡張メソッドを実装する
C#は配列のような組み込み型にもメソッド追加したりできるみたいなのでやってみます。
ArrayExtensionクラスに静的メソッドを追加する
public static class ArrayExtension {
public static void ForEach<T>(this T[] array, Action<T> action) {
for (int i = 0; i < array.Length; i++) {
action.Invoke(array[i]);
}
}
public static void ForEach<T>(this T[] array, Action<T, int> action) {
for (int i = 0; i < array.Length; i++) {
action.Invoke(array[i], i);
}
}
}
上が配列内の要素だけを使うもの、下が要素とindexを使うものです。 内容はシンプルで引数で受け取ったactionをfor文で回して実行してるだけです。 実行結果はこんな感じです。
C#に新たに追加したForEachメソッド
float[] audioSourceVolume = new float[] { 1.0f, 0.7f, 0.3f };
audioSourceVolume.ForEach((e, i) => { Debug.Log($"ch{i}のボリュームは{e}"); });
//結果
//ch0のボリュームは1
//ch1のボリュームは0.7
//ch2のボリュームは0.3
Javascriptと同じ感覚で書けるようになりました。 ForEachメソッドだとJavascriptの時と同様でcontinueやreturnが使えないといったデメリットもあるんですが、可読性高くサクサク書いていきたい時にはやっぱり重宝します。 パフォーマンスも関数呼び出しの分多少は落ちるでしょうがパフォーマンスを追求したい時はめんどくさがらずfor文で書けば済む話です。 でもせっかく自由にいじれるので