Il casting di un object in C # restituisce sempre un riferimento all’object iniziale

Attualmente sto facendo un progetto in C # che funziona con i moduli di Windows. Durante il corso, ho fatto quanto segue

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); } 

Lo scopo di questo codice è di avere un pulsante che nasconda tutti gli altri pulsanti nel contenitore in cui si trova tranne se stesso, e quindi trasformarsi in un pulsante Scopri che fa la stessa cosa al contrario.

Ora, va tutto bene, eccetto che, mentre compilo questo, mi rendo conto che ho avuto un problema. hider è il suo object unico, essendo il ritorno dal mittente ((pulsante)). Non è necessariamente il riferimento al mittente e questo codice probabilmente non farà nulla.

Ma basso ed ecco, funziona esattamente come lo volevo e inizialmente pensavo che sarebbe successo. Che mi ha fatto meravigliare, un cast restituisce sempre un riferimento all’object originale? In caso contrario, come posso garantire che (pulsante) mittente = mittente?

So che non è il caso di doppio / intatto, come

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

termina con un essere 11, e b che è 10.5 Ma ciò potrebbe essere dovuto al fatto che i duplicati sono strutture. Questo comportamento mi preoccupa, e sarebbe bello sapere che restituirà sempre un riferimento, così posso mettere a rest la mia preoccupante mente.

Per i tipi di riferimento. se il cast è solo in alto o in basso nella gerarchia dell’ereditarietà, allora sì. Questa è una conversione di riferimento . Dalle specifiche del linguaggio C # 3.0, sezione 6.2.4:

Le conversioni di riferimento, implicite o esplicite, non cambiano mai l’id quadro referenziale dell’object da convertire. In altre parole, mentre una conversione di riferimento può cambiare il tipo di riferimento, non cambia mai il tipo o il valore dell’object a cui si fa riferimento.

Questo è il caso che stai usando nel tuo codice WinForms.

Tuttavia, in altri casi (tipo di riferimento ancora) può invocare una conversione definita dall’utente . Per esempio:

 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 } } 

Le conversioni definite dall’utente come questa sono relativamente rare.

Per i tipi di valore, ci sono conversioni di boxing e unboxing, insieme ad altre conversioni (es. Tra int e double ).

Per i tipi di riferimento contenuti nella gerarchia di ereditarietà, farà sempre riferimento alla stessa istanza. Tuttavia, per i tipi di valore, i cast potrebbero riguardare il pugilato e l’unboxing che copieranno le cose. Oltre a questo, i cast non sono solo nella gerarchia dell’eredità. È ansible dichiarare il proprio operatore di cast che ha le caratteristiche di un metodo. Può restituire qualunque object piaccia.