La necessità di conversione esplicita del tipo in C #

7

Considera il seguente codice:

DerivedClass drbObj = (DerivedClass)obj;

Qui obj è di tipo Object e questo è ragionevole poiché Object è il tipo base di ogni Classe in C #.

Qui, poiché il tipo di derObj è definito in fase di compilazione, qual è la necessità di utilizzare esplicitamente la conversione dei tipi qui. Il compilatore non può prevedere da solo che sarà di DerivedClass . Capisco che, il tipo Conversion non debba corrispondere al tipo Derived , ma per scopi pratici, sarà utile solo quanto il tipo Derived .

Qualcuno potrebbe spiegare con un piccolo esempio ipotetico il motivo per cui la conversione del tipo esplicito è necessaria quando un riferimento di tipo Object viene assegnato a una classe derivata.

Da quanto so, in C, non è necessario eseguire la conversione del tipo Esplicito da void* a qualsiasi puntatore e il compilatore può gestirlo in base al tipo di puntatore a cui viene assegnato il valore convertito .

    
posta Shamim Hafiz 27.10.2011 - 12:55
fonte

4 risposte

9

Il motivo per cui devi farlo è piuttosto semplice:

Perché è così che è stato progettato il linguaggio.

Mentre sì, i progettisti C # potrebbero aver deciso di dedurre che il tuo intento era di lanciare obj basandosi esclusivamente sulla tua dichiarazione, hanno scelto di non farlo, probabilmente perché tale inferenza avrebbe causato più problemi di quanti ne abbia risolti.

Posso pensare a due motivi per cui potrebbero aver scelto di non dedurre il cast in DerivedObj:

1) Perché è incoerente. Anche se per l'assegnazione (come nel tuo esempio) può sembrare logico eseguire l'inferenza, ci sono un sacco di situazioni che ti occorrono per eseguire il cast in modo esplicito, e rendere il comportamento di casting coerente rende la lingua concettualmente più semplice. Per esempio, diciamo che stavi scrivendo un pezzo di codice che aveva bisogno di impostare l'ID dell'obj su 5, sapendo in anticipo che si trattava di DerivedObj. Dovresti ancora fare il cast:

((DerivedObj)obj).ID = 5;

2) Perché è pericoloso. Esecuzione del cast al compito è un "sei sicuro?" tipo di controllo che ti fa riflettere due volte su cosa sia realmente l'oggetto prima di assegnarlo. Direi che è una funzione della lingua, e sicuramente non vale un comportamento di casting caso speciale solo per l'assegnazione. Infatti, se hai davvero creato obj dicendo obj = new object() da qualche parte, il cast fallirà comunque.

    
risposta data 27.10.2011 - 13:58
fonte
3

Can't the compiler predict on it's own that it will be of DerivedClass.

No? Come diavolo potrebbe prevederlo? Vuoi che risolva il problema della Fermata? Gli oggetti possono essere inutili (e un disegno merdoso, merdoso) ma ci sono milioni di classi derivate da Object. Come potrebbe il compilatore sapere quale scegliere?

Il motivo per cui il cast è necessario è perché potrebbe fallire in fase di esecuzione e il compilatore vuole sapere che sei sicuro. Il casting esplicito è molto più sicuro del casting implicito.

From what I know, in C, there is no need to do perform Explicit type conversion from void* to any pointer and the compiler can handle it, based on the type of the pointer to which the converted value is being assigned.

Questa è una cosa cattiva , non una cosa buona e conversione! = casting. I cast sono cattivi. Cerca di non usarli.

    
risposta data 27.10.2011 - 13:35
fonte
1

Quando chiedi "perché", è importante porre due sotto-domande. Cosa ci guadagna e cosa ci fa perdere?

  1. Cosa ci guadagna?

Niente, in realtà. Immagino che tu voglia ridurre la copia incolla. Questo è un obiettivo ammirevole, ma il modo idioma C # per scrivere questo è in realtà:

var drbObj = (DerivedClass)obj;
  1. Cosa ci fa perdere?

Controlli in fase di compilazione sulla sicurezza runtime. Il compilatore di solito non sa per certo che obj terrà sempre un riferimento a un'istanza della classe derivata. Inoltre, non sa se sei disposto a rischiare un'eccezione di tipo casting non isolata qui. Non sa come gestire questa situazione in fase di compilazione.

Quando inserisci il cast esplicito, stai risolvendo il problema. Stai dicendo esplicitamente al compilatore, " I so che c'è un'istanza DerivedClass qui, e sono disposto a subire un'eccezione se sbaglio." Il compilatore fa quindi ciò che gli hai detto. Sarebbe piuttosto rischioso (il runtime si blocca senza preavviso? No grazie!) Per consentire al compilatore di decidere di farlo da solo.

    
risposta data 26.05.2015 - 08:56
fonte
0

Il linguaggio C # usa la sintassi cast per indicare un numero di cose diverse, a seconda dell'operando e dei tipi di risultato. Il significato qui è "Penso che l'operando sia un riferimento a una cosa di tipo X, e mi piacerebbe renderlo disponibile a qualcosa che richiede un riferimento di tipo X, lanciare un'eccezione se la cosa non è del tipo corretto.

Quando si tenta di scrivere qualsiasi tipo di codice corretto, è importante avere almeno alcuni tipi di istruzioni che possono essere garantite per non generare eccezioni a meno che un thread non venga interrotto bruscamente. Data una variabile locale x di qualche tipo di riferimento, è importante che se è possibile garantire la valutazione di alcuni expression di non generare un'eccezione, anche l'istruzione x = expression; .

Se x è di un tipo più derivato di y , l'espressione (typeOfX)y; potrebbe generare un'eccezione se y non può essere convertito nel tipo di x , ma l'istruzione x = (typeOfX)y; obbedisce regola che un'assegnazione a una variabile locale non può generare un'eccezione una volta completata la valutazione dell'argomento a destra. Poiché i downcast sono una situazione in cui possono essere generate eccezioni, richiedendo a un programmatore di scrivere x = (typeOfX)y; anziché solo x = y; , è chiaro che l'istruzione potrebbe generare un'eccezione.

    
risposta data 26.05.2015 - 21:29
fonte

Leggi altre domande sui tag