2012-08-31 15 views

risposta

26

No, non è unboxing - è solo controllando se il tipo di è corretta. Non dimenticare che c'è davvero un oggetto coinvolto, con un tipo. Il controllo di quel tipo è fondamentalmente la stessa operazione indipendentemente dal fatto che il valore sia o meno un valore di tipo valore in box. (Potrebbero essere possibili ottimizzazioni per tipi di valore o tipi sigillati, poiché non c'è eredità da considerare, ma fondamentalmente controlla ancora la parte "tipo" dell'intestazione di un oggetto.)

Un modo per verificare che sia compilato il codice e cerca nella iL utilizzando ILASM:

// object o = 10 
IL_0000: ldc.i4.s 10 
IL_0002: box  [mscorlib]System.Int32 
IL_0007: stloc.0 

// int i = (int) o; 
IL_0008: ldloc.0 
IL_0009: unbox.any [mscorlib]System.Int32 
IL_000e: stloc.1 

// bool isInt = o is int 
IL_000f: ldloc.0 
IL_0010: isinst  [mscorlib]System.Int32 

in modo che utilizza isinst - non unboxing è necessaria.

+2

Quindi il CLR può controllare un tipo senza unboxing? –

+3

@ViacheslavSmityukh: Sì. Non dimenticare che c'è davvero un oggetto coinvolto, con un tipo. Il controllo di quel tipo è fondamentalmente la stessa operazione indipendentemente dal fatto che il valore sia o meno un valore di tipo valore in box. –

+2

@JonSkeet Potresti modificare quel commento nella risposta, penso che spiegare * perché *, piuttosto che solo la prova attraverso IL sia particolarmente preziosa. – Servy

5

Non solo non richiede unboxing, logicamente, non può.

Unboxing può avere esito positivo o negativo, a seconda che l'oggetto contenga davvero un valore del tipo a cui tenteremo di annullare l'accesso.

Pertanto, unboxing richiede un controllo per verificare se l'oggetto è di quel tipo particolare.

Pertanto, se il test del tipo richiesto unboxing, quindi dal momento che richiede unboxing testare il tipo, non saremmo in grado di unboxing fino a quando avremmo primo unboxing ...

Pertanto la sperimentazione di un tipo può non richiedono unboxing.

0

A partire da C# 7, la parola chiave is ha ottenuto un nuovo caso d'uso, nella corrispondenza del modello come tipo di modello. In questo caso, unboxing si verifica per esempio:

object o = 10; 
if (o is int i) { 
    // i is the unboxed value. 
} 

Ovviamente, questo è un caso diverso al posto della originale dove è puramente testato il valore, come quando si usa is come un modello, in realtà si sta assegnando il valore. Da qui la necessità di unbox in questo caso.

Per essere chiari - non è cambiato nulla rispetto all'originale o is int - non ci sarà unboxing, come da vecchie risposte. La parola chiave is ha appena acquisito un nuovo ruolo.