背景
int[] hogeArray = {0, 1, 2, 3};といったHoge[]型の配列を使っていたのですが、hogeArray.Reverse()が使えないことに気づいたため急遽この記事を作成しています。
結論としては、Array.Reverse(hogeArray)を使うのが吉です。
- Unityのバージョン:2022.3.62
- OS:Windows 11 Home Edition 24H2
今回起きたこと
端的に言えばHoge[].Reverse()メソッドは戻り値として反転した配列を返すのですが、Hoge[]型ではなく、IEnumerable<Hoge>型を返します。
つまり、hogeArray = hogeArray.Reverse();と書くと型が合わずにエラーとなります。
ここまでだけだと、「エラーが出るなら罠じゃないじゃん」と思われるかもしれません。しかし、恐ろしい罠はこれとは別に存在しているのです。
恐ろしいのは、私が次に示すドキュメントのサンプルコードを見てこの関数の挙動を勘違いしてしまったことです。
Unity Script Reference – Array.Reverse
var hello = new Array ("Hello", "World");
hello.Reverse();
// prints World, Hello
print(hello);
ご覧になられましたか?戻り値で結果を返すのではなく、インスタンス内容を改変するような挙動として紹介されていますね。まあ、ちゃんと見れば`Hoge[]`型ではなく、`Array`型でのコードですので、今となっては同じ挙動しないのはわかります。
しかし、このドキュメントを見て`Hoge[]`型でもこの挙動になると勘違いしたままコードを書くとどうなるでしょうか?
そう、エラーが出ないので、バグの元となります。
しかも、配列変数が視覚的に表れない部分で使われていると、発覚が遅れます。
私はこれで4日溶かしました。
でも、こういうUnityとかのちゃんとしたところだと仕様は統一されていると思っちゃいますよね?Unityの安心感からそういう性善説が働いちゃいますよね?
エラーも出ず使えちゃうもんですから怖いですね。
そうはいっても、ちゃんと確認するコードを書かなかった私が悪いのは間違いないです。
回避策
Array.Reverse(hogeArray)を使いましょう。
こちらであればインスタンスを直接改変し、先ほどのサンプルコードを同じ感覚で使えます。
もっと広範な視点で見れば、似たようなことを起こさないために、サンプルコードをしっかり読んで性善説を適用しないとか、ネイティブのC#についてちゃんと知っておくだとかが対策になると思います。
以上です。