2009-06-30 24 views
10

Actualmente estoy haciendo un proyecto en C# trabajando con formularios de Windows. Durante el transcurso de la misma, hice lo siguiente¿El lanzamiento de un objeto en C# siempre devuelve una referencia al objeto inicial?

 void HideButtons(object sender, EventArgs e) 
    { 
     Button hider = ((Button)sender); 
     foreach(Button tohide in hider.Parent.Controls) 
      tohide.Hide(); 
     hider.Show(); 
     hider.Text = "UnHide"; 
     hider.Click -= new EventHandler(HideButtons); 
     hider.Click += new EventHandler(ShowButtons); 
    } 

El propósito de este código es tener un botón que oculta todos los otros botones en el contenedor está en excepto a sí misma, y ​​luego convertirse en un botón en Mostrar lo que hace lo mismo en reversa

Ahora, eso está muy bien, excepto que, mientras compilo esto, me doy cuenta de que me he topado con un problema. HIDER es su objeto único, que es el retorno de (remitente del botón). No es necesariamente la referencia al remitente, y este código probablemente no hará nada.

Pero bajo y, he aquí, funciona exactamente como yo quería y en un principio pensé que sería. Lo que me hizo preguntarme, ¿un reparto siempre devuelve una referencia al objeto original? De lo contrario, ¿cómo puedo garantizar que (botón) sender = sender?

sé que no es el caso para los dobles/enteros, como

 public static int Main() 
    { 
     int a; 
     double b; 
     b = 10.5; 
     a = (int)b; 
     a++; 
     return 0; 
    } 

termina con un ser 11, y siendo b 10,5 Pero eso puede ser debido a dobles/enteros son estructuras. Este comportamiento me preocupa, y sería bueno saber que siempre devolverá una referencia para que pueda poner mi mente preocupada a descansar.

+0

Excelente pregunta. Aquí hay algunas notas sobre cuándo un yeso cambia la representación frente a la preservación de la identidad. Puede ser bastante confuso. http://blogs.msdn.com/ericlippert/archive/2009/03/19/representation-and-identity.aspx –

Respuesta

16

Para tipos de referencia. si el elenco está arriba o abajo de la jerarquía de herencia, entonces sí. Esta es una conversión de referencia . A partir de la especificación del lenguaje C# 3.0, sección 6.2.4: conversiones

de referencia, implícita o explícita , sin cambiar el referencial identidad del objeto de ser convertidos . En otras palabras, aunque una conversión de referencia puede cambiar el tipo de la referencia, nunca cambia el tipo o el valor del objeto al que se hace referencia.

Este es el caso que está utilizando en su código de WinForms.

Sin embargo, en otros casos (aún tipo de referencia) puede invocar una conversión definida por el usuario. Por ejemplo:

using System; 

class Foo 
{ 
} 

class Bar 
{ 
    public static explicit operator Bar(Foo f) 
    { 
     return new Bar(); 
    } 
} 

class Test 
{ 
    static void Main() 
    { 
     Foo f = new Foo(); 
     Bar b = (Bar) f; 
     Console.WriteLine(object.ReferenceEquals(f, b)); // Prints False 
    } 
} 

conversiones definidas por el usuario de este tipo son relativamente raro.

Para los tipos de valor, hay conversiones de boxeo y desempaquetado, junto con otras conversiones (por ejemplo, entre int y double).

11

Para tipos de referencia lanzados a través de la jerarquía de herencia, siempre hará referencia a la misma instancia. Sin embargo, para los tipos de valor, los moldes pueden incluir boxeo y unboxing que copiarán cosas. Aparte de eso, los moldes no están solo en la jerarquía de herencia. Puede declarar su propio operador de reparto que tiene las características de un método. Puede devolver cualquier objeto que quiera.

+0

Soy nuevo en C#. ¿Hay alguna forma de averiguar si el objeto pasado es un value_type o un reference_type? – Naveen

+1

if (obj es ValueType) –

Cuestiones relacionadas