はなちるのマイノート

Unityをメインとした技術ブログ。自分らしくまったりやっていきたいと思いますー!

【Unity,C#】それって本当に配列やListでいいんでしょうか?

はじめに

こんにちは、先日松屋の横にスライドするドアを必死に押して開けようとしていたはなちるです。

最近ネットサーフィンをしていてこのような記事を見つけました。

qiita.com

見てみると非常に興味深かったです。

特にここは気を付けなきゃと感じたところ備忘録の意味合いもかねて少し抜粋してみたいと思います。

では早速やっていきましょう。

インターフェイスについて

本題に入る前に少しだけインターフェイスの話をさせてください。

インターフェイスには一般的により上位なインターフェイスほどできる機能が少ないという性質があります。

簡単な一例をみてみましょう。

名称 foreach / LINQ 要素の追加 / 削除 要素の順序関係 List 固有機能
IEnumerable - - -
ICollection - -
IList -
List

IEnumerable インターフェース してみる - ソーセージ の メモ書き

表の上の方が上位,下の方がより下位なインターフェイスです。(Listは普通のクラスですが)

これをみてもやはり上位のインターフェイスの方ができることが少ないことが分かりますよね。

まあ当然といえば当然なのですが、これがタイトルにあるような配列やListを使うのがあまり適切でないという状況を生みうる大きな理由になります。

リストの継承関係について

最初に紹介した記事をめちゃくちゃ参考にさせていただいて以下の画像を作ってみました。

f:id:hanaaaaaachiru:20191003023838p:plain

この図の上にあるほど上位なインターフェイスになります。

なぜこのような紹介をしたかというと、インターフェイスには以下のような重要な性質があるからです。

AクラスIXインターフェイスを実装していると、AオブジェクトIX型の変数に代入できる

【Unity】インターフェイスについてかるくまとめてみた - はなちるのマイノート

つまりはこういうことですね。

List<int> list = new List<int> { 1, 2, 3, 4, 5 };
IEnumerable<int> enumerable = list;

これを踏まえて今回一番伝えたいメソッドの引数・返り値について掘り下げていきたいと思います。

メソッドに引数

出来る限り上位のインターフェースにすると良いです。

void Hoge(IEnumerable<int> list)

例えば要素を追加・削除をしてほしくないのに、引数がListだと勝手に追加されてしまう可能性がでてきてしまいますよね。
(分かりやすさのためこう書きましたがやや語弊があるので後述にて言い直します)

なのでメソッド内で行う処理に必要最低限必要な機能を備えた引数にすることは大切になります。

メソッドの返り値

出来る限り下位のインターフェースにすると良いです。

List<int> Hoge()

メソッドの返り値でIEnumerableなどにして機能に制限をかける必要はほぼないと思います。

こちらは深く考えずにListとかを返しちゃいましょう。

あくまで目印

メソッドの引数・返り値について紹介しましたが、IEnumerableにはLINQと言われる強力な拡張メソッドが存在します。

このLINQを用いることで要素の順番なども楽々扱うことができてしまうのです。
【Unity】LINQと要素のインデックスについて - はなちるのマイノート

というかキャストも可能なのでIReadonly〇〇と書いてありながらやろうと思えばやりたい放題できます。


しかしそこは本質ではなくて、メソッドの名前や引数,返り値等(メソッドシグネチャ)を見ることで中でどのような処理が行われているのかを分かりやすいようにすることが大切だということです。

だからメソッド内でリストに要素を追加・削除をしないのに引数をListにしてしまうと、メソッドを使う人はもしかして要素が変更されるのではないかという不安を持ってしまうことになります。

是非最小限の機能だけにすることで安心をさせてあげましょう。

ただかくいう私自身も上手くできなくていつも悩んでいるのですが…。

さいごに

ただIEnumerable(LINQも)を扱うときは遅延評価という少し変わった挙動をするので注意が必要です。

慣れてくるまではIReadonlyListIReadonlyCollectionあたりを使うと良いかもしれませんね。

またもっと詳しくみてみたい方はこちらの記事を参考にしてみてください!
引数の型を何でも List にしちゃう奴にそろそろ一言いっておくか - Qiita