ノートの端の書き残し

UnityやらC#やら。設計が得意かもしれない。

【Unity】Unity Japanの動画で触れられていたTupleについての補足

Unity Japanの動画

www.youtube.com

動画の概要

  1. C#7から"タプル"が使えるよ。
  2. タプルは"匿名構造体"みたいなものだよ。
  3. タプルの作り方は柔軟で色々あるよ。
  4. タプルを作るときは、メンバに名前をちゃんとつけたほうがいいよ。
  5. タプルの使い方として、スワップ処理とかも楽に書けるよ。

補足する内容

動画自体は、かなり初心者向けに作られているように思います。初心者を混乱させることは省略して触れないようにしているなと。
なので、その多分意図的に省略してるっぽいところを補足しようと思います。

「2. タプルは"匿名構造体"みたいなものだよ。」について

動画で出てきたサンプルコードに関してはこれは間違いではないです。ただ、タプルにはValueTupleTupleがあり、動画に登場していたのは全てValueTuple。つまり、構造体のタプルです。じゃあTupleは何なのか。構造体との対比なんだから、クラスです。

// これは"ValueTuple"が生成されている
var (index, value) = (1, "要素1");
// これも"ValueTuple"が生成されている
ValueTuple<int, string> tuple = new(1, "要素1");
// これは"Tuple"、つまりクラスインスタンスが生成されている
Tuple<int, string> tuple = new(1, "要素1");

一般的に「タプル」と言うとValueTupleの方を指すのでややこしいですね。、クラスの方のタプルってほとんど使わないんですが(僕は使ったこと無いですねw)、Tupleと明示的に宣言してしまうとクラスになってしまうことは気を付けましょう。

「4. タプルを作るときは、メンバに名前をちゃんとつけたほうがいいよ。」について

その通りですね。ただ、これは実は内部的に名前が変わっているわけではなくて、コンパイラに対して、その名前のアクセスをItem1,2に置き換えるように指示を出しているだけだったりします。なので、(あんまりしないと思うけど)リフレクションとかで名前を文字列で指定してタプルのメンバにアクセスするようなケースは気を付けましょう。

sharplab.io

「5. タプルの使い方として、スワップ処理とかも楽に書けるよ。」

実は動画内でも一言触れているんですが、最適化の問題があります。
どう言うことかというと、普通に1つ一時変数を置けばスワップ処理ができるところを、タプルを使ったスワップ処理では2つ一時変数が確保されます。

sharplab.io

いやいやこの程度、と思うかもしれません。まぁほとんどのケースでは問題にならないと思います。使っていいでしょう。ただ、めちゃくちゃ頻繁に(1フレームに何百回とか)呼ばれるケースだとやめた方がいいです。
あと、ちゃんと一時変数確保してることは理解しておかないと、メンバが構造体のときには気付かないうちに結構差が出ますね。 (そういう状況をそもそも作るなとか、ポインタで参照置き換えた方がよくない?とか言えることありそうだけど……)

終わり

以上タプルの動画に対する補足でした。
結局コンパイラを意識しろって話かよ、と言う感じですが、C#で、ゲームという比較的パフォーマンスを重視する開発を行なっている以上、コンパイラを無視するのはちょっと無いかなぁと個人的には思います。