Pregunta

Cuando se realiza una conversión hacia arriba o abatido, lo que llegue realmente a suceder detrás de las escenas? Tenía la idea de que cuando se hace algo como:

string myString = "abc";
object myObject = myString;
string myStringBack = (string)myObject;

el reparto en la última línea tendría como única finalidad indicar al compilador que estamos seguros que no estamos haciendo nada malo. Por lo tanto, tuve la idea de que en realidad no hay código de fundición estaría incorporada en el propio código. Parece que estaba equivocado:

.maxstack 1
.locals init (
    [0] string myString,
    [1] object myObject,
    [2] string myStringBack)
L_0000: nop 
L_0001: ldstr "abc"
L_0006: stloc.0 
L_0007: ldloc.0 
L_0008: stloc.1 
L_0009: ldloc.1 
L_000a: castclass string
L_000f: stloc.2 
L_0010: ret 

¿Por qué la necesidad de CLR algo así como castclass string?

Hay dos posibles implementaciones para un abatido:

  1. Es necesario un castclass something. Al llegar a la línea de código que hace un castclass, el CLR intenta hacer el reparto. Pero entonces, ¿qué pasaría si hubiera omite, la línea de cuerda castclass y trató de ejecutar el código?
  2. Usted no necesita un castclass. Como todos los tipos de referencia tienen una estructura interna similar, si intenta utilizar una cadena en una instancia de formulario, se lanzará una excepción del uso incorrecto (ya que detecta un formulario no es una cadena o cualquiera de sus subtipos).

También, es el siguiente statamente de C # 4.0 en una cáscara de nuez correcto?

Upcasting and downcasting between compatible reference types performs reference
conversions: a new reference is created that points to the same object.

¿Es realmente crear una nueva referencia? Pensé que sería la misma referencia, sólo se almacena en un tipo diferente de variable.

Gracias

¿Fue útil?

Solución

Yo tenía la idea de que en realidad no hay código de fundición estaría incorporada en el propio código.

Una idea interesante. ¿Cómo se imagina que esto funcionó?

try
{
    object x = 123;
    object y = (string)x;
}
catch(InvalidCastException ex)
{ ... }

Si el yeso no produce ningún código a continuación, ¿de dónde viene el código que produce la excepción suceda

Recuerde, el propósito principal de un molde de un tipo menos específica a un tipo más específico es el de realizar una verificación de tipos en tiempo de ejecución .

Una vez que pasa la comprobación de tipo, entonces seguro, nada más realmente tiene que suceder. Los bits de la referencia antes de la comprobación de tipo y los bits después de la verificación tipo son los mismos bits; Hemos tenido el tiempo de ejecución verificar que el nuevo uso de los vestigios antiguos se justifica.

Si intenta utilizar una cadena en una instancia de formulario, que será una excepción del uso incorrecto (ya que detecta un formulario no es una cadena o cualquiera de sus subtipos).

¿Dónde se detecta que? Es decir, en exactamente qué instrucción es la detectada? En la instrucción castclass . Eso es lo que la instrucción es para castclass.

¿Qué pasaría si hubiera omite, la línea de cuerda castclass y trató de ejecutar el código?

El verificador de seguridad de tipo habría rechazado su programa. Si hubiera obligado a la CLR para ejecutarlo sin pasar la verificación entonces hubiera tenido un comportamiento indefinido. Podría haber tenido éxito, podría haber fallado, podría haber formateado el disco duro.

¿Es realmente crear una nueva referencia?

Recuerde, a nivel de implementación de referencia es sólo un número entero triple de tamaño. Es un número que el administrador de memoria se puede utilizar para realizar un seguimiento de la posición de la referida a los datos. Puede ser que sea un puntero, que podría ser un mango, no importa lo que es; Es algo que implementa la noción abstracta de una referencia.

Cuando se tiene una variable que contiene 12 y que "reemplazar" su contenido con el 12, que es un "nuevo" 12 que acaba de ser creado o se trata de la "vieja" 12? Suponga que ha hecho una segunda variable y poner 12 en ella también mediante la copia de la primera variable. Es que un "nuevo" 12 o la "vieja" 12? ¿Cómo puede saber? Es una diferencia que no hace ninguna diferencia. Cuando haces una "nueva" referencia que es idéntica a una referencia de "viejo" es que la creación de algo nuevo? La pregunta es una pregunta filosófica, no técnico.

Otros consejos

Estás confundiendo de referencia con instancia. Un nuevo referencia se crea, no es una nueva instancia.

object foo = "bar";
string baz = (string)foo;

Una nueva referencia a la "foo" cadena se asigna a la variable baz (pero todavía hay sólo una instancia de la cadena, es sólo que ambas variables apuntan a la única instancia). Si no fuera el caso, tendría algo parecido a un tipo "mango". Si baz y foo eran literalmente la misma referencia, entonces esto ..

foo = "bim";

También haría baz igual a "bim" (del mismo modo, la asignación de un tipo no haría cadena ya no baz apuntan a una cadena de referencia válido).

Puede realizar un yeso en un tipo de referencia, ya sea cuando están en la misma jerarquía de herencia (uno hereda de la otra, ya sea directa o indirectamente) o cuando existe una conversión explícita entre los tipos. Tenga en cuenta que las conversiones explícitas, como todos los otros operadores, no son polimórficos - es decir, la conversión debe definirse específicamente en una de las clases en cuestión , no en otro punto de la jerarquía

Una conversión explícita, cuando está presente, tendrá prioridad incluso si los tipos en cuestión son compatibles sin ella. En el caso de una conversión explícita, que no tiene ninguna garantía (de hecho, es bastante improbable) de que el resultado de la fundición / conversión apuntará a la misma instancia que el objeto que se está colando.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top