¿Pasar un tipo de valor en un parámetro "fuera" hace que la variable esté en caja?
-
24-10-2019 - |
Pregunta
Soy consciente de que El boxeo y el unboxing son relativamente caros En términos de rendimiento. Lo que me pregunto es:
Pasar un tipo de valor a un método out
Parámetro Causa Boxing/Unboxing de la variable (y, por lo tanto, un éxito de rendimiento)? ¿Puede el compilador optimizar esto?
int number;
bool result = Int32.TryParse(value, out number);
Solución
Como otros han señalado, no hay boxeo aquí. Cuando pasa una variable como un argumento correspondiente a un parámetro out o ref, lo que está haciendo es Hacer un alias para la variable. No estás haciendo nada al valor de la variable. Estás haciendo dos variables representando la misma ubicación de almacenamiento.
El boxeo solo ocurre cuando un valor de tipo de valor se convierte en un valor de un tipo de referencia, y no hay una conversión de ningún tipo en su ejemplo. El tipo de referencia debe ser, por supuesto, System.Object, System.ValueType, System.enum o cualquier interfaz. Por lo general, es bastante claro; Hay una conversión explícita o implícita en el código. Sin embargo, puede haber circunstancias en las que esté menos claro. Por ejemplo, cuando se llama un método virtual no superado del tipo base de una estructura, hay boxeo. (También hay situaciones extrañas en las que ciertos tipos de restricciones de tipo genérico pueden causar un boxeo inesperado, pero generalmente no aparecen en la práctica).
Otros consejos
Sin boxeo, el compilador utiliza la instrucción LDLOCA.S que empuja una referencia a la variable local en la pila (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
}
No, no hay boxeo (requerido/involucrado).
Cuando haces una variable de cuadro, los cambios en la instancia en caja no afectan el original. Pero eso es exactamente lo que out
se supone que debe hacer.
El compilador 'de alguna manera' construye una referencia a la variable original.
No hay boxeo; que out
El parámetro dokes especifica que el número debe asignarse dentro del TryParse
método. Independientemente de esto, todavía se trata como un int
, no un object
.