C#の代入式の評価値についてメモ
環境
- .Net Framework 4.5.1
- VisualStudio 2015 Professional
そもそも
C#では代入式(a=10みたいな式)は代入される値を返す。
int a;
bool b = (a = 10) == 10; //bはtrue
個人的にはパッと見何をやっているのかわかりにくいので基本的に使用しない。
イコール(=) 以外の代入式
代入式は単純な=
以外に+=
, -=
, *=
, /=
があるが、それぞれ評価値はそれぞれ計算後の値となる。
int a = 3;
int b = a *= 5;// aもbも15が入る
評価した値と代入される値が一致するので、a+=1
はa++
より++a
に近い。
本題
int a = 3;
a *= a += 5;
としたときのa
の値は何になるでしょうか?
やってみる前の予想では、
//a *= a += 5;の分解(予想)
int tmp = a += 5; //a=8, tmp=8
a *= tmp;
と実行されて、最終的にはa
に64(8 * 8)が入ると思っていた。
しかし実際にやってみるとa
には24 ((5 + 3) * 3)が入っている。
つまりは
//a *= a += 5;の分解
int tmp = a + 5;// a=3, tmp=8
a *= tmp;
となっているようで、右側の式は計算はされているが代入は無視されている?
また、
int a = b= 3;
a *= b += 5;
とすると、a=24, b=8となる。右側(先に評価される側)の代入が無視されるのは同じ変数に対する代入だけの模様。
さらに次のようにコードを変更してみる
int a = 3;
a *= ++a;
この場合はa
には12 (3 * (3 + 1))が入っている。
先ほど+=の挙動が前置インクリメントに近いと書いたが、ここでも挙動は一致する。
ちなみに
int a = 3;
a *= a++;
とすると、aには9が入る。
まとめ、感想
- 代入式は代入する値を返す
- +=等は計算後の値を返す
- 同じ変数について1行で2回代入すると、先に評価される箇所の代入は無視される?
- ただし計算付の代入の場合、計算結果を返す部分はのこる
- ILレベルで見ればもっと詳しい意味が分かると思うが、これ以上は深入りしないでおく
- 基本的には、代入式の評価値は使わない方がいいと思う(使った方がいい場面ってあるの?)
- C# Interactiveのおかげでこういう検証がやりやすくなった