2013-10-29 11 views
10

Quindi ho sempre pensato che il casting e la conversione in C# siano fondamentalmente la stessa cosa: due modi diversi per passare da un tipo di dati all'altro. Chiaramente questo non è corretto, poiché spesso generano risultati diversi.Tempo corretto per eseguire il cast e convertire in C#

Convert.ToInt32(1.6)  //outputs 2 
(Int32)1.6    //outputs 1 


(DateTime)("10/29/2013")   //won't compile - cannot convert type 'string' to type 'system.date.time' 
Convert.ToDateTime("10/29/2013") //outputs 10/29/2013 12:00:00 AM 
  • La mia domanda è che cosa è la differenza principale tra i due e perché tornano risultati diversi?
  • Qual è il momento "appropriato" per utilizzare l'uno sull'altro?

Personalmente mi trovo ad usare il metodo Convert.To come mi sembra più pulito. So che getta anche lo System.InvalidCastException. Qualcuno può fornire una spiegazione semplice?

+1

'Convert' fa un po 'di" magia "durante la conversione. Analizza il valore del tipo di origine e applica la trasformazione per creare una nuova istanza del tipo di destinazione. Il casting avviene a un livello inferiore e puoi solo trasmettere tipi correlati (ad esempio un numero in virgola mobile su un numero intero). – knittl

+0

@Kelix I tuoi esempi rispondono alle tue domande. Generalmente, il cast deve essere usato quando si ha ereditarietà. Usa Converti per trasformare una cosa in un'altra cosa quando non puoi trasmettere. – Candide

risposta

5

È possibile utilizzare fuso in due casi:

  • quando il tipo si sta casting per è un tipo che si sta lanciando da
  • quando explicit cast operator definita per questi tipi

In tutti gli altri casi dovresti usare Converti o altri metodi di conversione personalizzati (es. DateTime.Parse).

perché restituiscono risultati diversi?

Perché viene eseguito un codice diverso. Convert.ToInt32(double value) giri frutto di colata:

int num = (int) value; 
double num2 = value - num; 
if ((num2 > 0.5) || ((num2 == 0.5) && ((num & 1) != 0)))  
    num++; 

return num; 
1

Nella conversione metodo Convert.ToInt32 utilizza le seguenti regole per il suo valore di ritorno

valore, arrotondati al numero intero con segno a 32 bit più vicina. Se il valore è a metà strada tra due numeri interi, viene restituito il numero pari; che è, 4,5 viene convertito in 4, e 5.5 viene convertito in 6.

Tuttavia le norme per la explicit conversion sono diverse

Quando si converte un valore decimale a un tipo integrale, questo valore è arrotondato verso lo zero al valore integrale più vicino. Se il valore integrale risultante non rientra nell'intervallo del tipo di destinazione, viene generata una OverflowException .

Se si desidera il cast di operare lo stesso del Convert.ToInt32 [o vogliono specificare come l'arrotondamento avrebbe funzionato] allora si dovrebbe utilizzare il metodo Math.Round con un cast come segue.

(int)Math.Round(1.6) //outputs 2 

Esistono altre firme di metodo che consentono di specificare come arrotondare.

Per quanto riguarda quando si dovrebbe usare cast e la conversione, è necessario utilizzare il explicit cast quando possibile rendersi conto che si sta andando a perdere precisione quando si passa da una più precisa del tipo meno preciso di spedizione in modo appropriato e il convertito quando non ci si aspetta che i dati siano in un formato che può essere lanciato. quando possibile indica quando esiste una conversione esplicita (comprese le conversioni implicite). Le conversioni predefinite possono essere trovati in Section 6 della specifica

Un cast-espressione di E modulo (T), dove T è un tipo ed E è un unario espressione , esegue una conversione esplicita (Sezione 6.2) del valore di E per digitare T. Se non esiste una conversione esplicita dal tipo di E a T, si verifica un errore in fase di compilazione. In caso contrario, il risultato è il valore prodotto dalla conversione esplicita.

0

Non esiste una regola veloce su cui utilizzare in tutti i casi. Devi solo sapere cosa fa ciascuno e scegliere quello più appropriato per il tuo scenario. Come hai sottolineato te stesso, Conversione e cast possono produrre risultati diversi. La ragione è che Convert e cast possono avere implenentazioni totalmente diverse.

public static explicit operator MyStructA(MyStructB b) 
{ 
    MyStructA a = convert.ToMyStructA(b); 
    //I could do this so that convert and cast return the same but I don't have to. 

    return a; 
} 
Problemi correlati