2016-07-01 9 views
0

これは、値の種類]ボックスの質問についてです。(Int32)を どのように内部値型の回避ボックス


私はILコードをチェックし

が、私はILはInt32.ToString()を呼び出した、

とInt32.ToStringの下で、それらのネストされたメソッド()はボックスのアクションはありません、

私たちが知っているように値の型が参照型に変換する場合は、ボックスがあり、

とC#は、私たちに別の方法を与えることはありません。プロセスt彼の変容。


値の型は参照クラス(文字列)にどのように変換されますか?

答えて

3

値型のインスタンスメソッドを呼び出し、できるだけそれが静的コール又は呼び出し「制約」を使用します。タイプが必要なメソッド(objectの実装を必要とする)を実装していない限り、ボックスは必要ありません。なぜそれは箱が必要でしょうか?ただ、それを必要としないため作成しません。

注:これは、常には、値型を作成するときにすべてのメソッドをオーバーライドする必要があるためです。 ToString()(例えば)をオーバーライドしない場合、になります。を実行すると、仮想ベースメソッドを呼び出すためのボックスを作成する必要があります。をオーバーライドすると、コンパイラはオーバーライドを安全に呼び出すことができますそのインスタンスは決してnullではなく、このメソッドはサブタイプによってオーバーライドされることはありません。サイドノートとして

:コンパイラは、「制約」放出することもできますが、基本的に言ってJITへのハンドルを渡している値、タイプ、のためのすべてのケースにを呼び出します。

  • ターゲット場合参照タイプは、間接参照であり、ターゲットメソッドを実装値型である場合にそうでない場合は、仮想コール
  • を使用し、そうでなければ静的呼び出し
  • を使用し、逆参照、ボックス、および仮想呼び出し
を使用します

しかし、組み込み型(intなど)の場合、静的呼び出しを介してメソッドに直接移動する方が一般的です。デフォルトの "制約付き"アプローチの理由は、型を宣言するライブラリを変更した場合(実装の追加または削除)でも安全に使用できることです。

+0

Console.WriteLine( "123456 {0}"、3.ToString())を呼び出した場合。値タイプ3は、参照タイプ文字列でどのように結合しますか。何もボックスが必要ないと言っていますが、スタックフレーム上の3がヒープ上の文字列にどのように移動するのですか? –

+1

@LuffyDingは値のタイプ3をヒープに移動しません。 'ToString()'メソッドは 'string * 'となる*完全に無関係な新しいオブジェクトを作成し、長さ1と値50のユニコードコードポイントを含むようになります(これは、 3'')とおそらくゼロターミネータですが、これはスタック上の元の値とはほとんど関係がありません。具体的には –

+1

の "itoa"スタイルの演算を実行した値です。 'ldstr'、' ldc.i4.3'、 'call'(int.ToString())、' call'(string.Format(string、string))、 'call'(Console。WriteLine(文字列))(与えてください、実際には 'int.ToString'呼び出しを行うために' stloc'/'ldloca'ペアを使用しなければなりません) –

関連する問題