2011-12-02 7 views
5

Eventuali duplicati:
Casting: (NewType) vs. Object as NewType
Casting vs using the 'as' keyword in the CLRQuando usare() rispetto a 'come' per cambiare tipo?

//var gridView = (gridViewRow.NamingContainer as GridView); <-- works too 
var gridView = (GridView)gridViewRow.NamingContainer; 

mia comprensione incompleta di questo sta usando as parola chiave può dare null quando si utilizza un cast () sarà un'eccezione. Il mio obiettivo è essere in grado di chiedermi "in che modo devo lanciare?" e so come rispondere

+1

Questo è un duplicato di molte volte simile a http://stackoverflow.com/questions/496096/casting-vs-using-the-as-keyword-in-the-clr o http: // stackoverflow.com/questions/2483/casting-newtype-vs-object-as-newtype – Bert

risposta

5

Dipende, ma in fondo:

Se si conosce e può garantire che l'oggetto è il tipo si pensa che viene quindi utilizzare ().

Se esiste la possibilità che possa essere qualcos'altro, utilizzare as e verificare null. In questo caso si avrebbe:

var realThing = someObject as MyClass; 
if (realThing != null) 
{ 
    .... 
} 

È possibile utilizzare is a guardia della () che si tradurrebbe in:

if (someObject is MyClass) 
{ 
    var realThing = (MyClass)someObject; 
    .... 
} 

Ma questo si traduce in due conversioni, piuttosto che quello di as o cast dritto ().

Questo è il punto in cui "dipende". Dovresti decidere caso per caso che fosse più appropriato. Potresti anche avere degli standard di codifica da rispettare.

+0

per curiosità, che dire dell'utilizzo dell'operatore "is" per proteggere un uso di()? diverso? –

+0

@Gabriel - Guarda l'aggiornamento. – ChrisF

+2

Non si dovrebbe usare "is" per proteggere, poiché in questo caso si eseguiranno 2 conversioni. Se hai bisogno di quella funzionalità, converti con "come" e controlla null. –

3

la questione è più di

Come voglio il mio codice per affrontare un fallimento fusione dinamica?

Se si dispone di un contratto implicito/esplicito che gridViewRow.NamingConainer è in realtà una GridView poi un () cast è appropriato. Se il tipo non è un GridView ha violato un contratto, viene generata un'eccezione e l'errore sarà evidente. Tuttavia, se è possibile che non si tratti di un GridView e si desidera gestire in modo proattivo il caso, è opportuno specificare as.

In questo caso sembra che il contratto implicito sia uno GridView e quindi continuerei a utilizzare (). Se sei andato con as e il contratto è stato interrotto ti ritroverai con uno NullReferenceException che in realtà non è il problema. Il problema è che il tipo non era uno GridView come previsto e quindi InvalidCastException è molto più appropriato

+0

+1 per la punta per riflettere sulla chiarezza del significato dell'eccezione risultante nel caso di errore –

1

La mia regola generale è che se so che è il tipo che sto trasmettendo a I use() s. Ad esempio, userei un cast diretto in un condizionale che ha già controllato il tipo. Se non sono sicuro, di solito uso 'come'.

0

Se si sa che gridViewRow.NamingContainer è un GridView, sì, utilizzare (GridView) per trasmettere. Chiaramente, il codice che segue non gestisce null, quindi se il tuo assunto è sbagliato, ottieni un'eccezione in entrambi i casi. L'uso di (GridView) per il cast renderà l'eccezione utile per te come programmatore, perché l'eccezione mostrerà la linea che ha il bug nella sua traccia dello stack.

Se non si sa se gridViewRow.NamingContainer è un GridView, è possibile combinare 'if (gridViewRow.NamingContainer è GridView) {... (GridView) gridViewRow.NamingContainer ...}' in un 'come' conversione.

0

Secondo here, la differenza sta nel modo in cui vengono gestiti gli errori nella conversione. Per riassumere:

  • () un'eccezione se il cast non è valido, cioè, se la variabile non è una sottoclasse del cast.
  • as, al contrario, restituirà un puntatore nullo, offrendo prestazioni leggermente migliori al costo di un debug più difficile.
Problemi correlati