同僚が私にこれを尋ねた場合、私の頭が混乱した状態で、答えがありませんでした:
あなたができるのはなぜですか:
string ham = "ham " + 4;
だがしかし:
string ham = 4;
を連結するときに文字列変換の暗黙のキャスト/操作がある場合、それを文字列として割り当てるときに同じではないのはなぜですか? (もちろん、演算子のオーバーロードを行わずに)
コンパイラーを連結すると、ステートメント"ham" + 4
がへの呼び出しに変わりますString.Concat
。これは2つのobject
パラメーターを受け取るため、値4
はボックス化ToString
されてから呼び出されます。
int
割り当ての場合、からへの暗黙の変換はないため、明示的に変換せずにstring
に割り当てることはできません。4
string
つまり、2つの割り当ては、C#で非常によく似ているにもかかわらず、コンパイラーによって非常に異なる方法で処理されます。
連結を行う場合、暗黙の変換はありません。文字列の連結は、Objectsを受け取るオーバーロードを持つString.Concat呼び出しに解決されます。文字列への(明示的な)変換を実行するのはこのオーバーロードです。
最初の式の右辺の値は文字列ですが、2番目の式の右辺の値は文字列ではありません。連結は、割り当てが特別なことを何もしていない最初のシナリオで魔法を提供します。2番目のシナリオでは、割り当ては引き続きダムを再生します。
表現
"ham " + 4
文字列型と加算演算子の組み合わせに基づいて、4を文字列に暗黙的に変換します。具体的には、「+」演算子の品質であり、演算子のオーバーロードを実行するときに、同じタイプのものを手動で実装できます。
同様のあまり明白でない例は次のようになります。
long myNumber = Int64.MaxValue-1;
この場合、「1」は32ビット整数として評価される必要がありますが、暗黙的に変換されます。コンパイラでサポートされている暗黙的な変換の完全なリストについては、C#言語仕様のセクション6.1を確認してください。
編集:明確にするために、私が参照した言語仕様のセクションには、コンパイラーによってサポートされる暗黙の変換がリストされていますが、「+」などの演算子は、独自のサポートされる変換を持つことができます。