ValueTupleを使うと一時変数を使わずに変数のスワップができるというのを聞いたので試してみました。
とりあえずやってみる
言われるがままにintの変数を2つ用意してスワップしてみました。
var a = 1; var b = 3; // スワップ前 // a = 1, b = 3 Console.WriteLine($"a = {a}, b = {b}"); (a, b) = (b, a); // スワップ後 // a = 3, b = 1 Console.WriteLine($"a = {a}, b = {b}");
(a, b) = (b, a)の部分でValueTupleを使ってaとbをスワップしてます。普通に左から順番に代入したらaとbは同じ値になっちゃうと思ったんですが、実行結果はちゃんとスワップされてました。ちょっと謎だったのでもう少し調べてみました。
逆コンパイルしてみる
さきほどのコードをビルドしてできたdllをILSpyで逆コンパイルしてみます。
int a = 1; int b = 3; Console.WriteLine($"a = {a}, b = {b}"); int num = b; int num2 = a; a = num; b = num2; Console.WriteLine($"a = {a}, b = {b}");
(a, b) = (b, a)の部分でnumとnum2という一時変数が登場してます。一時変数に一度代入したあとにaとbにそれぞれ代入しています。一見すると一時変数を使わずにスワップしているように見えましたが、裏ではちゃんと仕事していました。