È Boxing/unboxing, attuato attraverso la fine o l'inizio di associazione(ie.in fase di runtime o in fase di compilazione)?

StackOverflow https://stackoverflow.com/questions/8410308

  •  29-10-2019
  •  | 
  •  

Domanda

Per esempio:

int i=10;
object o = i; //late or early??

Allo stesso modo,

object o = "11";
int i = (int)o;//late or early??
È stato utile?

Soluzione

È boxing e unboxing, attuato attraverso la fine o l'inizio di associazione?Che è, è l'associazione fatto a runtime o a tempo di compilazione?

Io sono un po ' confuso da quella domanda."Vincolante" è in genere usato per indicare il risultato di un qualche tipo di analisi."L'associazione anticipata" di solito significa che qualche nome è stato associato con un certo metodo di slot in fase di compilazione;"late binding" associa il nome con la slot in fase di runtime.Che cosa si intende per "associazione" qui, nel contesto della boxe?

Immagino intendi dire che l'associazione tardiva entra in gioco solo per metodo e per le chiamate di metodo e non per l'assegnazione di operazioni/tipo di conversioni.Per implementare il binding dinamico facciamo riferimento oggetti derivati con base di variabili di classe.

Che non è esattamente quello che intendevo;Io sto usando le chiamate al metodo come un esempio canonico che illustra la differenza tra l'inizio e tardiva.Vedo il tuo punto meglio ora;l'analisi che determina precisamente il modo in cui viene eseguita la conversione può essere effettuata anche in fase di runtime o a tempo di compilazione e quindi in un certo senso anche una forma di "late binding" o "early binding".

Prendiamo un esempio di questa conversione:

int x = Whatever();
short y = (short)x;

Che la conversione esplicita è interamente "legato" al momento della compilazione.Il compilatore sa che l'operando è un int, che il tipo di destinazione è breve, che la conversione sarà effettuata da troncare i quattro byte int a due byte short.La conversione è, naturalmente, in realtà eseguite in fase di esecuzione.

Ora facciamo un po ' meno chiaro:

int x = Whatever();
short y = checked((short)x);

La conversione esplicita è ancora collegato al momento della compilazione.Sappiamo che l'operazione verrà eseguita.Ma sappiamo anche che in fase di runtime, il valore int sarà controllata per assicurarsi che si inserisce in un breve.

Non che contano come "late binding" nel tuo libro?Alcune analisi viene eseguita in fase di compilazione, ma alcune analisi viene eseguita in fase di runtime.

Ora consideriamo la boxe:

int x = Whatever();
object q = x;

Questo è interamente analizzato al momento della compilazione.Il compilatore sa che q è un oggetto e x è un int, e quindi dovrà emanare istruzioni casella di int in fase di runtime.

Che cosa circa l'unboxing?

int x = Whatever();
object q = x;
int y = (int)q;

Ciò che l'analisi viene effettuata in fase di compilazione?Tutti sappiamo che in fase di compilazione è che è un unboxing di conversione.Il tipo effettivo controllo è fatto in fase di runtime.È che una forma di "late binding", perché per un tipo di controllo viene eseguito in fase di esecuzione, con la tua definizione di associazione tardiva?

Che ne dici di questo?

int x = Whatever();
object q = x;
int y = (short)q;

Che genera un'eccezione in fase di esecuzione.In fase di compilazione sappiamo che è un unboxing di conversione.In fase di runtime non facciamo i "late binding" per dire "ehi, ho una confezione di int, mi permetta di capire come convertire un unboxed breve".Piuttosto, diciamo che "stiamo cercando di unbox int a breve;lanciare un'eccezione".Una confezione di T può solo essere privi di un T o un nullable T.

Così è unboxing "associazione anticipata" o "tardiva"?È presto vincolato, nel senso che sappiamo al momento della compilazione che è un unboxing di conversione.È tardiva, nel senso che facciamo un controllo di tipo a runtime.Non è tardiva, nel senso che non siamo in fase di runtime ri-fare il tipo di analisi che sarebbe stato fatto per un int-a-breve di conversione a tempo di compilazione.

Che dire di questo?

int x = Whatever();
object q = x;
int y = Convert.ToInt16(q);

o

int x = Whatever();
dynamic q = x;
int y = (int)q;

Ora abbiamo fare eseguire tutte le analisi in fase di esecuzione;in entrambi i casi abbiamo a che fare con il tipo di analisi di q in fase di esecuzione, stabilire che q è un boxed int, e "late binding" la conversione.

Tutto chiaro?È difficile rispondere alla tua domanda, perché è un po ' vago per quanto riguarda proprio quello che si intende per "late binding" una conversione.La parte di analisi è il "legame" per te?

Altri suggerimenti

La boxe viene cotta nelle istruzioni IL al momento della compilazione se è quello che stai cercando.

Se provi a smontare in un tipo diverso dal tipo originale, verrà lanciata un'eccezione. Ex#1, succede solo a Box implicitamente (tipo di valore per il tipo di riferimento). Ex#2 Un cast non valido esplode in fase di esecuzione.

Non sono sicuro di quanto la rilegatura precoce o tardiva entri in scena.

Il compilatore emetterà istruzioni di boxe che potrai vedere in IL. Dato codice

int item = 10;
object obj = item;
item = (int)obj;

Compilerai in qualcosa di simile

IL_0000:  ldc.i4.s    0A 
IL_0002:  stloc.0     
IL_0003:  ldloc.0     
IL_0004:  box         System.Int32
IL_0009:  stloc.1     
IL_000A:  ldloc.1     
IL_000B:  unbox.any   System.Int32
IL_0010:  stloc.0     

Nella seconda versione, questo farà esplodere. Un oggetto di stringa di tipo non può essere lanciato su un numero intero.

Il C# compila le istruzioni eseguite in fase di esecuzione.

La boxe implica un costo di runtime (non irresistibile); La boxe e unboxing possono causare errori di runtime (come illustra il tuo esempio "int i = (int) o").

Il "legame tardivo" vs "legame precoce" implica che qualcosa è "dinamico" (ad esempio, il legame di runtime del metodo virtuale di alcuni oggetti). In questo caso, la boxe è "fissa". Quindi immagino che tu possa dire che è "binding precoce".

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top