ボックス化とボックス化解除は、パフォーマンスの点で比較的高価であることを認識しています。私が疑問に思っているのは:
メソッドのout
パラメーターに値の型を渡すと、変数のボックス化/ボックス化解除が発生しますか (したがって、パフォーマンスが低下します)? コンパイラはこれを最適化できますか?
int number;
bool result = Int32.TryParse(value, out number);
ボックス化とボックス化解除は、パフォーマンスの点で比較的高価であることを認識しています。私が疑問に思っているのは:
メソッドのout
パラメーターに値の型を渡すと、変数のボックス化/ボックス化解除が発生しますか (したがって、パフォーマンスが低下します)? コンパイラはこれを最適化できますか?
int number;
bool result = Int32.TryParse(value, out number);
他の人が指摘しているように、ここにはボクシングはありません。out または ref パラメーターに対応する引数として変数を渡す場合、変数のエイリアスを作成していることになります。変数の値に対して何もしていません。2 つの変数が同じストレージの場所を表すようにしています。
ボクシングは、値型の値が参照型の値に変換された場合にのみ発生し、例にはいかなる種類の変換もありません。参照型は、もちろん、System.Object、System.ValueType、System.Enum、または任意のインターフェイスである必要があります。通常はかなり明確です。コードに明示的または暗黙的な変換があります。ただし、それがあまり明確でない状況もある可能性があります。たとえば、構造体の基本型のオーバーライドされていない仮想メソッドが呼び出されると、ボクシングが発生します。(特定の種類のジェネリック型制約が予期しないボックス化を引き起こす奇妙な状況もありますが、実際には通常は発生しません。)
コンパイラは、ローカル変数への参照をスタックにプッシュする ldloca.s 命令を使用します (http://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.ldloca_s(VS. 71).aspx)
.method private hidebysig static void Func() cil managed
{
.maxstack 2
.locals init (
[0] int32 num,
[1] bool flag)
L_0000: nop
L_0001: ldstr "5"
L_0006: ldloca.s num
L_0008: call bool [mscorlib]System.Int32::TryParse(string, int32&)
L_000d: stloc.1
L_000e: ret
}
いいえ、ボクシングはありません(必須/関与)。
変数をボックス化すると、ボックス化されたインスタンスへの変更は元のインスタンスには影響しません。しかし、それはまさにout
やるべきことです。
コンパイラは「何らかの方法で」元の変数への参照を構築します。
ボクシングはありません。out
パラメータが行うことは、メソッドTryParse
内で番号を割り当てる必要があることを指定することです。int
これに関係なく、ではなくとして扱われobject
ます。