Differenza tra il casting e l'utilizzo del metodo Convert.To ()


91

Ho una funzione che lancia un valore doublesu string.

string variable = "5.00"; 

double varDouble = (double)variable;

È stata archiviata una modifica del codice e il progetto viene compilato con l'errore: System.InvalidCastException: Specified cast is not valid.

Tuttavia, dopo aver eseguito le seguenti operazioni ...

string variable = "5.00"; 

double varDouble = Convert.ToDouble(variable);

... il progetto si costruisce senza errori.

Qual è la differenza tra il casting e l'utilizzo del Convert.To()metodo? Perché il lancio lancia un Exceptione l'uso di Convert.To()non lo fa?

c#  casting 


6
Per quanto riguarda una domanda referenziata , l'OP chiede quando usare un cast o convertire, e la risposta accettata afferma: "È davvero una questione di scelta, qualunque cosa tu usi". Sto chiedendo la differenza tra un cast e un convertito. A mio parere, le risposte di seguito (complimenti SO!) Forniscono maggiori dettagli sulle differenze rispetto a "usare questo o quello per scelta" ... e questo dettaglio potrebbe essere utilizzato per fare una scelta più informata, in sostanza.

@ edmastermind29 non c'è molta differenza tra "qual è la differenza tra x e y" e "quando usare x e y" nel contesto di programmazione. Entrambi rispondono reciprocamente all'altro.
nawfal

2
Quasi 3 anni dopo, in questo caso non sembra che l'uno risponda reciprocamente all'altro. D: "Qual è la differenza tra X e Y?" A: "È davvero una questione di scelta quello che usi." Non molto utile.

Nessuno sembra avere una risposta diretta a quale rendimento migliore sia anche parte della domanda, dalla mia esperienza vedo che Cast è migliore soprattutto nell'ottenere valori di colonna come questo .. (int) datatable.Rows [0] [0], if sappiamo che è int al 100%
Sundara Prabu

Risposte:


127

Anche se si può vedere in qualche modo equivalenti sono completamente diverse in proposito. Proviamo prima a definire cos'è un cast:

Il casting è l'azione di cambiare un'entità di un tipo di dati in un altro.

È un po 'generico ed è in qualche modo equivalente a una conversione perché un cast spesso ha la stessa sintassi di una conversione, quindi la domanda dovrebbe essere quando un cast (implicito o esplicito) è consentito dalla lingua e quando devi usare un ( più) conversione esplicita?

Vorrei prima tracciare una linea semplice tra di loro. Formalmente (anche se equivalente per la sintassi del linguaggio) un cast cambierà il tipo mentre una conversione cambierà / potrebbe cambiare il valore (eventualmente insieme al tipo). Anche un cast è reversibile mentre una conversione potrebbe non esserlo.

Questo argomento è piuttosto vasto, quindi proviamo a restringerlo un po 'escludendo gli operatori di cast personalizzati dal gioco.

Cast impliciti

In C # un cast è implicito quando non perderai alcuna informazione (tieni presente che questo controllo viene eseguito con i tipi e non con i loro valori effettivi ).

Tipi primitivi

Per esempio:

int tinyInteger = 10;
long bigInteger = tinyInteger;

float tinyReal = 10.0f;
double bigReal = tinyReal;

Questi cast sono impliciti perché durante la conversione non perderai alcuna informazione (devi solo allargare il tipo). Viceversa il cast implicito non è consentito perché, indipendentemente dai loro valori effettivi (perché possono essere verificati solo in fase di esecuzione), durante la conversione potresti perdere alcune informazioni. Ad esempio, questo codice non verrà compilato perché a doublepuò contenere (e in realtà lo fa) un valore non rappresentabile con a float:

// won't compile!
double bigReal = Double.MaxValue;
float tinyReal = bigReal;

Oggetti

Nel caso di un oggetto (un puntatore a) il cast è sempre implicito quando il compilatore può essere certo che il tipo di origine è una classe derivata (o implementa) il tipo della classe di destinazione, ad esempio:

string text = "123";
IFormattable formattable = text;

NotSupportedException derivedException = new NotSupportedException();
Exception baseException = derivedException;

In questo caso il compilatore sa che stringimplementa IFormattablee che NotSupportedExceptionè (deriva da) Exceptionquindi il cast è implicito. Nessuna informazione viene persa perché gli oggetti non cambiano il loro tipo (questo è diverso con se con structi tipi primitivi perché con un cast crei un nuovo oggetto di un altro tipo ), ciò che cambia è la tua visione di essi.

Cast espliciti

Un cast è esplicito quando la conversione non viene eseguita in modo implicito dal compilatore e quindi è necessario utilizzare l'operatore cast. Di solito significa che:

  • Potresti perdere informazioni o dati, quindi devi esserne consapevole.
  • La conversione potrebbe non riuscire (perché non puoi convertire un tipo in un altro) quindi, ancora una volta, devi essere consapevole di quello che stai facendo.

Tipi primitivi

È richiesto un cast esplicito per i tipi primitivi quando durante la conversione potresti perdere alcuni dati, ad esempio:

double precise = Math.Cos(Math.PI * 1.23456) / Math.Sin(1.23456);
float coarse = (float)precise;

float epsilon = (float)Double.Epsilon;

In entrambi gli esempi, anche se i valori rientrano floatnell'intervallo, si perderanno le informazioni (in questo caso la precisione) quindi la conversione deve essere esplicita. Ora prova questo:

float max = (float)Double.MaxValue;

Questa conversione fallirà quindi, ancora una volta, deve essere esplicita in modo che tu ne sia consapevole e puoi fare un controllo (nell'esempio il valore è costante ma potrebbe provenire da alcuni calcoli di runtime o I / O). Torna al tuo esempio:

// won't compile!
string text = "123";
double value = (double)text;

Questo non verrà compilato perché il compilatore non può convertire il testo in numeri. Il testo può contenere qualsiasi carattere, non solo numeri e questo è troppo, in C #, anche per un cast esplicito (ma potrebbe essere consentito in un'altra lingua).

Oggetti

Le conversioni da puntatori (a oggetti) potrebbero non riuscire se i tipi non sono correlati, ad esempio questo codice non verrà compilato (perché il compilatore sa che non è possibile alcuna conversione):

// won't compile!    
string text = (string)AppDomain.Current;
Exception exception = (Exception)"abc";

Questo codice verrà compilato ma potrebbe non riuscire in fase di esecuzione (dipende dal tipo effettivo di oggetti sottoposti a cast) con un InvalidCastException:

object obj = GetNextObjectFromInput();
string text = (string)obj;

obj = GetNextObjectFromInput();
Exception exception = (Exception)obj;

Conversioni

Quindi, infine, se i cast sono conversioni, perché abbiamo bisogno di classi come Convert? Ignorando le sottili differenze che derivano dall'implementazione Converte dalle IConvertibleimplementazioni in realtà perché in C # con un cast dici al compilatore:

credimi, questo tipo è quel tipo anche se non puoi saperlo ora, fammelo fare e vedrai.

-o-

non preoccuparti, non mi interessa se qualcosa andrà perso in questa conversione.

Per qualsiasi altra cosa è necessaria un'operazione più esplicita (si pensi alle implicazioni dei cast facili , ecco perché il C ++ ha introdotto per loro una sintassi lunga, dettagliata ed esplicita). Ciò può comportare un'operazione complessa (per la conversione string-> doublesarà necessaria un'analisi). Una conversione a string, ad esempio, è sempre possibile (tramite ToString()metodo) ma può significare qualcosa di diverso da quello che ti aspetti quindi deve essere più esplicito di un cast ( più scrivi, più pensi a quello che stai facendo ).

Questa conversione può essere eseguita all'interno dell'oggetto (utilizzando istruzioni IL note per questo), utilizzando operatori di conversione personalizzati (definiti nella classe da eseguire il cast) o meccanismi più complessi ( TypeConverterso metodi di classe, ad esempio). Non sei consapevole di cosa succederà per farlo, ma sei consapevole che potrebbe fallire (ecco perché IMO quando è possibile una conversione più controllata dovresti usarlo). Nel tuo caso la conversione analizzerà semplicemente il stringper produrre un double:

double value = Double.Parse(aStringVariable);

Ovviamente questo potrebbe fallire, quindi se lo fai dovresti sempre catturare l'eccezione che potrebbe lanciare ( FormatException). È fuori tema qui, ma quando a TryParseè disponibile, dovresti usarlo (perché semanticamente dici che potrebbe non essere un numero ed è ancora più veloce ... fallire).

Le conversioni in .NET possono provenire da molti luoghi, TypeConvertercast impliciti / espliciti con operatori di conversione definiti dall'utente, implementazione IConvertiblee metodi di analisi (ho dimenticato qualcosa?). Dai un'occhiata a MSDN per maggiori dettagli su di loro.

Per concludere questa lunga risposta, solo poche parole sugli operatori di conversione definiti dall'utente. È solo zucchero lasciare che il programmatore usi un cast per convertire un tipo in un altro. È un metodo all'interno di una classe (quella che verrà lanciata) che dice "ehi, se lui / lei vuole convertire questo tipo in quel tipo allora posso farlo io". Per esempio:

float? maybe = 10; // Equals to Nullable<float> maybe = 10;
float sure1 = (float)maybe; // With cast
float sure2 = maybe.Value; // Without cast

In questo caso è esplicito perché potrebbe fallire ma questo è lasciato all'implementazione (anche se ci sono linee guida in merito). Immagina di scrivere una classe stringa personalizzata come questa:

EasyString text = "123"; // Implicit from string
double value = (string)text; // Explicit to double

Nella tua implementazione potresti decidere di "semplificare la vita del programmatore" e di esporre questa conversione tramite un cast (ricorda che è solo una scorciatoia per scrivere di meno). Alcune lingue possono persino consentire questo:

double value = "123";

Consentire la conversione implicita in qualsiasi tipo (il controllo verrà eseguito in fase di esecuzione). Con le opzioni appropriate questo può essere fatto, ad esempio, in VB.NET. È solo una filosofia diversa.

Cosa posso fare con loro?

Quindi la domanda finale è quando dovresti usare l'uno o l'altro. Vediamo quando puoi usare un cast esplicito:

  • Conversioni tra tipi di base.
  • Conversioni da objecta qualsiasi altro tipo (questo può includere anche l'unboxing).
  • Conversioni da una classe derivata a una classe base (o a un'interfaccia implementata).
  • Conversioni da un tipo a un altro tramite operatori di conversione personalizzati.

Solo la prima conversione può essere eseguita, Convertquindi per gli altri non hai scelta e devi usare un cast esplicito.

Vediamo ora quando puoi usare Convert:

  • Conversioni da qualsiasi tipo di base a un altro tipo di base (con alcune limitazioni, vedere MSDN ).
  • Conversioni da qualsiasi tipo implementato IConvertiblea qualsiasi altro tipo (supportato).
  • Conversioni da / a un bytearray a / da una stringa.

Conclusioni

IMO Convertdovrebbe essere utilizzato ogni volta che sai che una conversione potrebbe non riuscire (a causa del formato, dell'intervallo o perché potrebbe non essere supportato), anche se la stessa conversione può essere eseguita con un cast (a meno che non sia disponibile qualcos'altro). Rende chiaro a chi leggerà il tuo codice qual è il tuo intento e che potrebbe fallire (semplificando il debug).

Per tutto il resto è necessario utilizzare un cast, nessuna scelta, ma se è disponibile un altro metodo migliore allora ti consiglio di usarlo. Nel tuo esempio una conversione da stringa doubleè qualcosa che (specialmente se il testo proviene dall'utente) molto spesso fallirà, quindi dovresti renderla il più esplicita possibile (inoltre hai più controllo su di essa), ad esempio utilizzando un TryParsemetodo.

Modifica: qual è la differenza tra loro?

Secondo la domanda aggiornata e mantenendo ciò che ho scritto prima (su quando puoi usare un cast rispetto a quando puoi / devi usare Convert), l'ultimo punto per chiarire è se ci sono differenze tra loro (inoltre Convertusi IConvertiblee IFormattableinterfacce in modo che possa eseguire operazioni non consentito con calchi).

La risposta breve è sì, si comportano diversamente . Vedo la Convertclasse come una classe di metodi di supporto così spesso che fornisce alcuni vantaggi o comportamenti leggermente diversi. Per esempio:

double real = 1.6;
int castedInteger = (int)real; // 1
int convertedInteger = Convert.ToInt32(real); // 2

Piuttosto diverso, vero? Il cast viene troncato (è quello che tutti ci aspettiamo) ma Convertesegue un arrotondamento all'intero più vicino (e questo potrebbe non essere previsto se non ne sei consapevole). Ogni metodo di conversione introduce differenze, quindi una regola generale non può essere applicata e devono essere viste caso per caso ... 19 tipi di base da convertire in ogni altro tipo ... l'elenco può essere piuttosto lungo, molto meglio consultare MSDN caso per caso Astuccio!


Ho cambiato la domanda da fare, Difference between casting and using the Convert.To() method. Altrimenti, risposta molto esauriente. (Spero che la mia domanda venga riaperta ...)

@ edmastermind29 Ho modificato un po 'la domanda, l'argomento è troppo lungo anche per una risposta lunga (300+ conversioni possibili da elencare). Convert aggiunge vantaggi (o solo comportamenti inaspettati?) Non solo rispetto ai cast, ma anche rispetto alle interfacce IConvertible e IFormattable "semplici".
Adriano Repetti

Non mi piace l'idea presa in prestito da C secondo doublecui i valori che non rappresentano numeri interi dovrebbero essere "convertibili" in int. Un cast sembrerebbe il paradigma appropriato nei casi in cui ad esempio si stanno recuperando Int32valori da un double[]che contiene un mix di numeri reali e Int32valori che sono stati convertiti in double[un tentativo di convertire un valore che non è rappresentabile precisamente in int32indicherebbe una condizione inaspettata e dovrebbe attivare un'eccezione], ma penso che quando si desidera una conversione con perdita di dati si dovrebbe essere specifici sulla forma che si desidera.
supercat

1
Un'altra differenza è tra i tipi oggetto e primitivi. ad esempioobject o = 123; var l = Convert.ToInt64(o); var i = (long) (int) o; var f = (long) o // InvalidCastException
yue shi

1
@ rory.ap questo è un punto importante. No, formalmente questo non è un cast ( float-> int) ma una coercizione . Un cast potrebbe essere ad esempio DerivedClass-> BaseClass. È fonte di confusione perché in C # usiamo la stessa parola (e operatore) per entrambi, ma in realtà sono cose distinte. Una definizione formale per distinguerli è leggermente più complicata di quanto ho scritto.
Adriano Repetti

13

Il casting è un modo per dire al compilatore: "So che pensi che questa variabile sia una barra, ma mi capita di saperne più di te; l'oggetto è in realtà un Foo, quindi lascia che lo tratti come se fosse un Foo di adesso. " Quindi, in fase di esecuzione, se l'oggetto effettivo si è rivelato essere davvero un Foo, il tuo codice funziona, se risulta che l'oggetto non era affatto un Foo, ottieni un'eccezione. (In particolare un System.InvalidCastException.)

La conversione, d'altra parte, è un modo per dire: "Se mi dai un oggetto di tipo Bar, posso creare un nuovo oggetto Foo che rappresenta ciò che è in quell'oggetto Bar. Non cambierò l'oggetto originale, ha vinto" Per trattare l'oggetto originale in modo diverso, creerà qualcosa di nuovo che si basa solo su un altro valore . Per quanto riguarda il modo in cui lo farà, potrebbe essere qualsiasi cosa. Nel caso in Convert.ToDoublecui finirà per chiamareDouble.Parseche ha tutti i tipi di logica complessa per determinare quali tipi di stringhe rappresentano quali valori numerici. Potresti scrivere il tuo metodo di conversione che mappi le stringhe ai doppi in modo diverso (forse per supportare alcune convenzioni completamente diverse per la visualizzazione dei numeri, come i numeri romani o altro). Una conversione potrebbe fare qualsiasi cosa, ma l'idea è che in realtà non stai chiedendo al compilatore di fare qualcosa per te; sei tu a scrivere il codice per determinare come creare il nuovo oggetto perché il compilatore, senza il tuo aiuto, non ha modo di sapere come mappare (ad esempio) a stringad a double.

Quindi, quando ti converti e quando lanci? In entrambi i casi abbiamo qualche variabile di un tipo, diciamo A, e vogliamo avere una variabile di tipo B. Se il nostro oggetto A davvero, effettivamente, sotto il cofano, è una B, allora lanciamo. Se non è realmente un B, allora dobbiamo convertirlo e definire come il programma dovrebbe ottenere un B da un A.


In uno dei post SO Eric Lippert ha detto che non esiste una cosa chiamata cast implicito ed è una conversione implicita . Ho usato cast e conversione in modo intercambiabile. cosa c'è di sbagliato nel dire "cast implicito"? Se la conversione è implicita senza richiedere alcun cast, si può dire che è un "cast implicito"?
rahulaga_dev

1
@RahulAgarwal Cos'è un cast è un'operazione in cui è necessario indicare esplicitamente che un determinato tipo è (o può essere trasformato in) un'istanza valida di un altro tipo. Quando esiste una conversione implicita, non è necessario alcun cast per trattare il tipo come un altro tipo. Quindi dire "cast implicito" non ha davvero senso (tranne che per le poche situazioni potenzialmente menzionate da Eric in cui viene aggiunto un operatore cast senza che lo sviluppatore lo digiti, come quando si usa a foreach). Al di fuori di queste eccezioni, i cast sono per definizione espliciti.
Servy

6

Da MSDN:

Conversioni esplicite (cast): le conversioni esplicite richiedono un operatore cast. Il cast è necessario quando le informazioni potrebbero andare perse durante la conversione o quando la conversione potrebbe non riuscire per altri motivi. Esempi tipici includono la conversione numerica in un tipo con una precisione minore o un intervallo più piccolo e la conversione di un'istanza della classe base in una classe derivata.

Considera il seguente esempio:

double a = 2548.3;
int b;
b = (int)a; //2548 --> information (.3) lost in the conversion

E anche:

Un cast è un modo per informare esplicitamente il compilatore che intendi effettuare la conversione e che sei consapevole che potrebbe verificarsi una perdita di dati.

Puoi usare System.Convertclass quando vuoi convertire tra tipi non compatibili . La principale differenza tra casting e convert è la compilazione e il runtime . Le eccezioni di conversione del tipo vengono visualizzate in fase di esecuzione , ovvero un cast di tipo che non riesce in fase di esecuzione causerà il InvalidCastExceptionlancio di un.


Conclusione: nel casting stai dicendo al compilatore che aè veramente di tipo be in tal caso il progetto viene compilato senza errori come questo esempio:

double s = 2;
int a = (int) s;

Ma nella conversione stai dicendo al compilatore v'è un modo per creare un nuovo oggetto da adi tipo b, si prega di farlo e progetto si basa senza errori ma come ho detto se il tipo di getto non riesce a run-time, che causerà un InvalidCastExceptiona essere gettato .

Ad esempio, il codice seguente non viene mai compilato perché il compilatore rileva che non può eseguire il cast di un'espressione di tipo DateTimein tipo int:

DateTime s = DateTime.Now;
int a = (int)(s);

Ma questo è stato compilato con successo:

DateTime s = DateTime.Now;
int a = Convert.ToInt32(s);

Ma in fase di esecuzione otterrai InvalidCastExceptionche dice:

Trasmissione non valida da "DateTime" a "Int32".


4

Nel tuo esempio stai tentando di eseguire il cast di una stringa su un double (tipo non integrale).

Perché funzioni è necessaria una conversione esplicita.

E devo sottolineare che avresti potuto usare Convert.ToDoubleinvece di Convert.ToInt64come puoi perdere le parti frazionarie del doppio valore quando converti in un int.

se la tua variabile ha il valore "5.25" varDouble sarebbe stata 5.00 (perdita di 0.25 a causa della conversione in Int64)

Per rispondere alla tua domanda su casting e conversione.

Il tuo cast (un cast esplicito) non soddisfa i requisiti per un cast esplicito. il valore che stai tentando di eseguire il cast con l'operatore cast non è valido (cioè non integrale).

Visita questa pagina MSDN per le regole di casting / conversioni


@ edmastermind29 ho aggiornato la mia risposta. spero che risponda alla tua domanda.
scartag

Quali sono i requisiti per un cast esplicito ... in relazione alla mia domanda? Riguarda il valore "non integrale"?

@ edmastermind29 Sì. se il valore che stai tentando di trasmettere a un tipo numerico non è numerico, il cast non è valido .. è richiesta una conversione.
scartag

4

Il Convert.Doublemetodo in realtà chiama solo internamente il Double.Parse(string)metodo.

Né il Stringtipo né il Doubletipo definiscono una conversione esplicita / implicita tra i due tipi, quindi il casting fallirà sempre.

Il Double.Parsemetodo esaminerà ogni carattere in stringe creerà un valore numerico basato sui valori dei caratteri in string. Se uno qualsiasi dei caratteri non è valido, il Parsemetodo fallisce (causando il Convert.Doublefallimento anche del metodo).


1
E come si differenzia da un cast esplicito?

3
Un cast esplicito non guarda quale sia il tipo di dati, guarda solo i byte. Un esempio potrebbe essere il cast di char x = '1' a un numero intero, il numero intero sarebbe 49 perché il carattere '1' è # 49 nella tabella ascii
user1751547

@ user1751547 Quindi, l'utente di uno Convert.ToDouble()sguardo oltre i byte e prenderebbe in considerazione i dati?

@ user1751547 Penso che sia il tipo di intuizione necessaria per rispondere adeguatamente a questa domanda. Dire semplicemente "non è definito" è un po 'discutibile.
Ant P

@ edmastermind29 Sì, controllerebbe il tipo di input e se fosse una stringa passerebbe attraverso ogni carattere, sapendo che se il valore ASCII del char era 49, allora è il carattere '1' e lo converte correttamente
user1751547

3

Il casting non comporta alcuna conversione, ovvero la rappresentazione interna di un valore non viene modificata. Esempio:

object o = "Hello"; // o is typed as object and contains a string.
string s = (string)o; // This works only if o really contains a string or null.

Puoi convertire un doublein in stringquesto modo

double d = 5;
string s = d.ToString(); // -> "5"

// Or by specifying a format
string formatted = d.ToString("N2"); // -> "5.00"

Puoi convertire a stringin a doublein diversi modi (qui solo due):

string s = "5";
double d = Double.Parse(s); // Throws an exception if s does not contain a valid number

O in modo sicuro

string s = "5";
double d;
if (Double.TryParse(s, out d)) {
    Console.WriteLine("OK. Result = {0}", d);
} else {
    Console.WriteLine("oops!");
}

Convert.ToDouble()internamente chiamaDouble.Parse() . E 'a mio vantaggio per l'uso Convert.ToDouble()sopra Double.Parse()o no, e perché?

Convert.ToDoubleha molti sovraccarichi che accettano diversi tipi di input. Il sovraccarico che accetta stringrestituisce 0.0se nullviene passata una stringa. A parte questo, non vedo vantaggi nell'usarlo.
Olivier Jacot-Descombes

Quindi, o o ... o Double.Parse()ha qualcosa da offrire che dovrei considerare?

Double.Parse()è più diretto di Convert.ToDouble(). Se sei sicuro che la tua stringa conterrà un numero valido, puoi tranquillamente usarlo, altrimenti ti consiglio di usare Double.TryParse.
Olivier Jacot-Descombes

1
string variable = "5.00";     
double varDouble = (double)variable;

La conversione di cui sopra semplicemente non è consentita dalla lingua. Ecco un elenco di cast espliciti per i tipi numerici: http://msdn.microsoft.com/en-us/library/yht2cx7b.aspx Come puoi vedere, anche non tutti i tipi numerici potrebbero essere convertiti in un altro tipo numerico

Altre informazioni sul casting qui

E in cosa differisce da Convert.ToDouble ()?

Quando si esegue il cast di un tipo, la struttura dei dati non viene modificata. Bene, in caso di conversione di valori numerici potresti perdere pochi bit o ottenere pochi bit 0 aggiuntivi. Ma stai ancora lavorando con un numero. Stai solo modificando la quantità di memoria occupata da quel numero. Questo è abbastanza sicuro perché il compilatore faccia tutto il necessario.

Ma quando si tenta di eseguire il cast di una stringa su un numero, non è possibile farlo perché non è sufficiente modificare la quantità di memoria occupata dalla variabile. Ad esempio, 5.00poiché una stringa è una sequenza di "numeri": 53 (5) 46 (.) 48 (0) 48 (0) - che è per ASCII, ma la stringa conterrà qualcosa di simile. Se il compilatore prenderà solo i primi N (4 per double? Non sei sicuro) byte da una stringa, quel pezzo conterrà un numero doppio completamente diverso. Allo stesso tempo Convert.ToDouble () esegue uno speciale algoritmo che prenderà ogni simbolo di una stringa, calcolerà la cifra che rappresenta e creerà un doppio numero per te, se la stringa rappresenta un numero. Linguaggi come PHP chiameranno Convert.ToDouble per te in background. Ma C #, come un linguaggio tipizzato staticamente, non lo farà per te. Ciò ti consente di essere sicuro che qualsiasi operazione sia sicura per i tipi e non otterrai qualcosa di inaspettato facendo qualcosa come:

double d = (double)"zzzz"

@ edmastermind29 vedi la mia risposta aggiornata. Ho provato a spiegarlo. La spiegazione è tutt'altro che perfetta, ma supponiamo che spieghi la differenza.
Viktor S.

1

Il cast di una stringa in un double del genere non è consentito C #, motivo per cui si ottiene un'eccezione, è necessario convertire la stringa ( documento MSDN che mostra percorsi di conversione accettabili). Questo è semplicemente perché una stringa non conterrà necessariamente dati numerici, ma i vari tipi numerici lo faranno (salvo valori nulli). A Converteseguirà un metodo che controllerà la stringa per vedere se può essere trasformata in un valore numerico. Se è possibile, restituirà quel valore. Se non può, genererà un'eccezione.

Per convertirlo, hai diverse opzioni. Hai usato il Convertmetodo nella tua domanda, c'è Parseche è in gran parte simile a Convert, ma dovresti anche guardare TryParse che ti permetterebbe di fare:

string variable = "5.00"; 

double varDouble;

if (Double.TryParse(variable, out varDouble)) {
    //Code that runs if the conversion succeeded.
} else {
    //Code that runs if the conversion failed.
}

Ciò evita la possibile eccezione se si tenta di Converto Parseuna stringa non numerica.


È a mio vantaggio utilizzare un TryParseover Convertperché TryParsecontrolla se la conversione ha successo?

@ edmastermind29 Penso di sì. Convert genererà un'eccezione se la conversione fallisce. TryParse restituirà un valore booleano, True se la conversione ha esito positivo e False se non riesce.
Keen

1

double varDouble = (double)variablepresume che variablesia già un doppio. Se variablenon è un doppio (è una stringa), l'operazione fallirà. double varDouble = Convert.ToDouble(variable)fa come dice - converte. Se può analizzare o altrimenti estrarre un double da, variablelo farà.

Secondo Double.Parseo Double.TryParseperché indica più chiaramente cosa dovrebbe succedere. Stai iniziando con una stringa e ti aspetti che sia convertibile in un doppio. In caso di dubbio, usa TryParse.

Se variableè un argomento del metodo, cambia il tipo in double. Rendere il chiamante responsabile di fornire il tipo corretto. In questo modo il compilatore fa il lavoro per te.


-1

La differenza più importante è che se viene utilizzato il casting del tipo e la conversione fallisce (diciamo che stiamo convertendo un valore float molto grande in int) non verrà generata alcuna eccezione e verrà mostrato il valore minimo che un int può contenere. Ma in caso di utilizzo di Convert , verrà generata un'eccezione per tali scenari.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.