Diferencia entre la conversión y el uso del método Convert.To ()

89

Tengo una función que proyecta una doubleen stringvalores.

string variable = "5.00"; 

double varDouble = (double)variable;

Se registró un cambio de código y el proyecto se compila con el error: System.InvalidCastException: Specified cast is not valid.

Sin embargo, después de hacer lo siguiente ...

string variable = "5.00"; 

double varDouble = Convert.ToDouble(variable);

... el proyecto se construye sin errores.

¿Cuál es la diferencia entre lanzar y usar el Convert.To()método? ¿Por qué lanzar un lanzamiento Exceptiony usar el Convert.To()no?


fuente
suena así 1. Cuándo usar un Cast o Convertir 2. Métodos de
conversión
6
Con respecto a una pregunta referenciada , el OP pregunta cuándo usar un molde o convertir, y la respuesta aceptada dice: "Realmente es una cuestión de elección lo que use". Estoy preguntando la diferencia entre un elenco y un converso. En mi opinión, las respuestas a continuación (¡felicitaciones, SO!) Brindan más detalles sobre las diferencias versus "usar esto o aquello por elección" ... y este detalle podría usarse para tomar una decisión más informada, en esencia.
@ edmastermind29 no hay mucha diferencia entre "cuál es la diferencia entre xey" y "cuándo usar xey" en el contexto de programación. Ambos responden mutuamente al otro.
Nawfal
2
Casi 3 años después, no parece que uno responda mutuamente en este caso. P: "¿Cuál es la diferencia entre X e Y?" R: "Es realmente una cuestión de elección lo que utilice". No es muy útil.
Nadie parece tener una respuesta directa a cuál de ellos se desempeña mejor también es parte de la pregunta. Desde mi experiencia, veo que Cast es mejor, especialmente para obtener valores de columna como este .. (int) datatable.Rows [0] [0], if sabemos que es 100% int
Sundara Prabu

Respuestas:

126

Incluso si puede verlos de alguna manera como equivalentes, tienen un propósito completamente diferente. Primero intentemos definir qué es un elenco:

La conversión es la acción de cambiar una entidad de un tipo de datos a otro.

Es un poco genérico y de alguna manera es equivalente a una conversión porque un elenco a menudo tiene la misma sintaxis de una conversión, por lo que la pregunta debería ser cuándo el lenguaje permite un elenco (implícito o explícito) y cuándo debe usar un ( más) conversión explícita?

Permítanme primero dibujar una línea simple entre ellos. Formalmente (incluso si es equivalente para la sintaxis del lenguaje) un elenco cambiará el tipo mientras que una conversión cambiará / puede cambiar el valor (eventualmente junto con el tipo). Además, un yeso es reversible mientras que una conversión puede no serlo.

Este tema es bastante amplio, así que intentemos reducirlo un poco excluyendo a los operadores de lanzamiento personalizados del juego.

Repartos implícitos

En C #, una conversión está implícita cuando no perderá ninguna información (tenga en cuenta que esta verificación se realiza con tipos y no con sus valores reales ).

Tipos primitivos

Por ejemplo:

int tinyInteger = 10;
long bigInteger = tinyInteger;

float tinyReal = 10.0f;
double bigReal = tinyReal;

Estas conversiones son implícitas porque durante la conversión no perderá ninguna información (solo amplía el tipo). No se permite la conversión implícita viceversa porque, independientemente de sus valores reales (porque solo se pueden verificar en tiempo de ejecución), durante la conversión puede perder algo de información. Por ejemplo, este código no se compilará porque a doublepuede contener (y de hecho lo hace) un valor no representable con a float:

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

Objetos

En el caso de un objeto (un puntero a), la conversión siempre está implícita cuando el compilador puede estar seguro de que el tipo de origen es una clase derivada (o implementa) el tipo de la clase de destino, por ejemplo:

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

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

En este caso, el compilador sabe que stringimplementa IFormattabley que NotSupportedExceptiones (deriva de) Exceptionpor lo que la conversión es implícita. No se pierde información porque los objetos no cambian sus tipos (esto es diferente con structsy tipos primitivos porque con un reparto creas un nuevo objeto de otro tipo ), lo que cambia es tu vista de ellos.

Repartos explícitos

Una conversión es explícita cuando el compilador no realiza la conversión implícitamente y luego debe usar el operador de conversión. Por lo general, significa que:

  • Puede perder información o datos, por lo que debe ser consciente de ello.
  • La conversión puede fallar (porque no puede convertir un tipo a otro) así que, nuevamente, debe estar consciente de lo que está haciendo.

Tipos primitivos

Se requiere una conversión explícita para tipos primitivos cuando durante la conversión puede perder algunos datos, por ejemplo:

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

float epsilon = (float)Double.Epsilon;

En ambos ejemplos, incluso si los valores se encuentran dentro del floatrango, perderá información (en este caso precisión), por lo que la conversión debe ser explícita. Ahora prueba esto:

float max = (float)Double.MaxValue;

Esta conversión fallará, así que, nuevamente, debe ser explícita para que lo sepa y pueda hacer una verificación (en el ejemplo, el valor es constante pero puede provenir de algunos cálculos en tiempo de ejecución o E / S). Volviendo a tu ejemplo:

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

Esto no se compilará porque el compilador no puede convertir texto en números. El texto puede contener cualquier carácter, no solo números y esto es demasiado, en C #, incluso para una conversión explícita (pero puede estar permitido en otro idioma).

Objetos

Las conversiones de punteros (a objetos) pueden fallar si los tipos no están relacionados, por ejemplo, este código no se compilará (porque el compilador sabe que no hay conversión posible):

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

Este código se compilará pero puede fallar en tiempo de ejecución (depende del tipo efectivo de objetos fundidos) con un InvalidCastException:

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

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

Conversiones

Entonces, finalmente, si los elencos son conversiones, ¿por qué necesitamos clases como Convert? Ignorando las sutiles diferencias que provienen de la Convertimplementación y las IConvertibleimplementaciones, en realidad porque en C # con un elenco le dices al compilador:

créame, este tipo es de ese tipo, incluso si no puede saberlo ahora, déjeme hacerlo y lo verá.

-o-

no se preocupe, no me importa si algo se perderá en esta conversión.

Para cualquier otra cosa , se necesita una operación más explícita (piense en las implicaciones de conversiones fáciles , por eso C ++ introdujo una sintaxis larga, detallada y explícita para ellos). Esto puede implicar una operación compleja (para string-> doubleconversión se necesitará un análisis sintáctico). Una conversión a string, por ejemplo, siempre es posible (a través del ToString()método) pero puede significar algo diferente de lo que esperas, por lo que debe ser más explícito que un elenco (cuanto más escribes, más piensas en lo que estás haciendo ).

Esta conversión se puede hacer dentro del objeto (usando instrucciones de IL conocidas para eso), usando operadores de conversión personalizados (definidos en la clase a emitir) o mecanismos más complejos ( TypeConverters o métodos de clase, por ejemplo). No está al tanto de lo que sucederá para hacer eso, pero sabe que puede fallar (por eso, en mi opinión, cuando es posible una conversión más controlada , debe usarla). En su caso, la conversión simplemente analizará el stringpara producir un double:

double value = Double.Parse(aStringVariable);

Por supuesto, esto puede fallar, por lo que si lo hace, siempre debe detectar la excepción que puede lanzar ( FormatException). Está fuera de tema aquí, pero cuando a TryParseestá disponible, debe usarlo (porque semánticamente dice que puede que no sea un número y es aún más rápido ... fallar).

Las conversiones en .NET pueden provenir de muchos lugares, TypeConverterconversiones implícitas / explícitas con operadores de conversión definidos por el usuario, implementación IConvertibley métodos de análisis (¿olvidé algo?). Eche un vistazo a MSDN para obtener más detalles sobre ellos.

Para terminar esta larga respuesta, solo unas pocas palabras sobre los operadores de conversión definidos por el usuario. Es simplemente genial dejar que el programador use un molde para convertir un tipo en otro. Es un método dentro de una clase (el que será lanzado) que dice "oye, si él / ella quiere convertir este tipo a ese tipo, entonces puedo hacerlo". Por ejemplo:

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

En este caso, es explícito porque puede fallar, pero esto se deja a la implementación (incluso si hay pautas al respecto). Imagina que escribes una clase de cadena personalizada como esta:

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

En su implementación, puede decidir "hacer la vida del programador más fácil" y exponer esta conversión a través de un reparto (recuerde que es solo un atajo para escribir menos). Algunos idiomas incluso pueden permitir esto:

double value = "123";

Permitiendo la conversión implícita a cualquier tipo (la verificación se realizará en tiempo de ejecución). Con las opciones adecuadas, esto se puede hacer, por ejemplo, en VB.NET. Es solo una filosofía diferente.

¿Qué puedo hacer con ellos?

Entonces, la pregunta final es cuándo debe usar uno u otro. Veamos cuándo puedes usar un elenco explícito:

  • Conversiones entre tipos de base.
  • Conversiones de objecta cualquier otro tipo (esto también puede incluir el desembalaje).
  • Conversiones de una clase derivada a una clase base (o a una interfaz implementada).
  • Conversiones de un tipo a otro mediante operadores de conversión personalizados.

Solo se puede realizar la primera conversión, por Convertlo que para las demás no tiene otra opción y necesita usar un elenco explícito.

Veamos ahora cuándo puedes usar Convert:

  • Conversiones de cualquier tipo base a otro tipo base (con algunas limitaciones, consulte MSDN ).
  • Conversiones de cualquier tipo que se implemente IConvertiblea cualquier otro tipo (admitido).
  • Conversiones de / a una bytematriz a / desde una cadena.

Conclusiones

La OMI Convertdebe usarse cada vez que sepa que una conversión puede fallar (debido al formato, debido al rango o porque puede no ser compatible), incluso si la misma conversión se puede hacer con una conversión (a menos que haya algo más disponible). Deja en claro quién leerá su código cuál es su intención y que puede fallar (simplificando la depuración).

Para todo lo demás, necesita usar un yeso, no hay opción, pero si hay otro método mejor disponible, le sugiero que lo use. En su ejemplo, una conversión de stringa doublees algo que (especialmente si el texto proviene del usuario) muy a menudo fallará, por lo que debe hacerlo lo más explícito posible (además, obtiene más control sobre él), por ejemplo, utilizando un TryParsemétodo.

Editar: ¿cuál es la diferencia entre ellos?

De acuerdo con la pregunta actualizada y manteniendo lo que escribí antes (sobre cuándo puede usar un molde en comparación con cuándo puede / debe usar Convert), el último punto a aclarar es si hay diferencias entre ellos (además, Convertusos IConvertiblee IFormattableinterfaces para que pueda realizar operaciones no permitido con yesos).

La respuesta corta es sí, se comportan de manera diferente . Veo la Convertclase como una clase de métodos auxiliares con tanta frecuencia que proporciona algún beneficio o comportamientos ligeramente diferentes. Por ejemplo:

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

Bastante diferente, ¿verdad? El reparto se trunca (es lo que todos esperamos) pero Convertrealiza un redondeo al número entero más cercano (y esto puede no ser esperado si no lo sabe). Cada método de conversión introduce diferencias, por lo que no se puede aplicar una regla general y deben verse caso por caso ... 19 tipos base para convertir a cualquier otro tipo ... la lista puede ser bastante larga, mucho mejor consultar el caso de MSDN por ¡caso!

Adriano Repetti
fuente
He cambiado la pregunta que hacer, Difference between casting and using the Convert.To() method. De lo contrario, respuesta muy completa. (Espero que mi pregunta se vuelva a abrir ...)
@ edmastermind29 Edité un poco la pregunta, el tema es demasiado largo incluso para una respuesta larga (más de 300 conversiones posibles para enumerar). Convert agrega beneficios (¿o simplemente comportamientos inesperados?) No solo frente a los casts, sino también frente a las interfaces "simples" IConvertible e IFormattable.
Adriano Repetti
No me gusta la noción tomada de C de que los doublevalores que no representan números enteros deberían ser "convertibles" a int. Un elenco parecería el paradigma apropiado en los casos en los que, por ejemplo, uno está recuperando Int32valores de un double[]que contiene una combinación de números reales y Int32valores que se han convertido en double[un intento de convertir un valor que no es representable con precisión en int32indicaría una condición inesperada y debería activar una excepción], pero creo que cuando uno quiere una conversión con pérdidas debería ser específico sobre la forma que quiere.
supercat
1
Otra diferencia es de objetos a tipos primitivos. por ejemploobject o = 123; var l = Convert.ToInt64(o); var i = (long) (int) o; var f = (long) o // InvalidCastException
yue shi
1
@ rory.ap ese es un punto importante. No, formalmente eso no es un reparto ( float-> int) sino una coacción . Un elenco podría ser, por ejemplo, DerivedClass-> BaseClass. Es confuso porque en C # usamos la misma palabra (y operador) para ambos, pero en realidad son cosas distintas. Una definición formal para distinguirlos es un poco más complicada de lo que escribí.
Adriano Repetti
12

La transmisión es una forma de decirle al compilador: "Sé que piensas que esta variable es una barra, pero resulta que yo sé más que tú; el objeto es en realidad un Foo, así que déjame tratarlo como si fuera un Foo de ahora en adelante ". Luego, en tiempo de ejecución, si el objeto real resultó ser realmente un Foo, entonces su código funciona, si resulta que el objeto no era un Foo en absoluto, entonces obtiene una excepción. (Específicamente un System.InvalidCastException.)

Por otro lado, convertir es una forma de decir: "Si me da un objeto de tipo Bar, puedo crear un objeto Foo nuevo que represente lo que hay en ese objeto Bar. No cambiaré el objeto original, ganó". Si trata el objeto original de manera diferente, creará algo nuevo que simplemente se basa en algún otro valor . En cuanto a cómo lo hará, podría ser cualquier cosa. En el caso de Convert.ToDoubleque termine llamandoDouble.Parseque tiene todo tipo de lógica compleja para determinar qué tipos de cadenas representan qué valores numéricos. Puede escribir su propio método de conversión que asigne cadenas a dobles de manera diferente (quizás para admitir alguna convención completamente diferente para mostrar números, como números romanos o lo que sea). Una conversión podría hacer cualquier cosa, pero la idea es que no le está pidiendo al compilador que haga nada por usted; usted es quien escribe el código para determinar cómo crear el nuevo objeto porque el compilador, sin su ayuda, no tiene forma de saber cómo mapear (como ejemplo) a stringa a double.

Entonces, ¿cuándo te conviertes y cuándo lanzas? En ambos casos tenemos alguna variable de un tipo, digamos A, y queremos tener una variable de tipo B. Si nuestro objeto A realmente, en realidad, bajo el capó, es una B, entonces lanzamos. Si no es realmente una B, entonces debemos convertirla y definir cómo se supone que el programa obtiene una B de una A.

Servy
fuente
En una de las publicaciones de SO, Eric Lippert mencionó que no existe tal cosa llamada reparto implícito y es conversión implícita . He estado usando reparto y conversión indistintamente. ¿Qué hay de malo en decir "reparto implícito"? ¿No es que si la conversión es implícita sin requerir ningún reparto, se puede decir que es un "reparto implícito"?
rahulaga_dev
1
Lo @RahulAgarwal un molde es una operación en la que usted necesita explícitamente indicar que un determinado tipo es (o puede ser hecho en) una instancia válida de otro tipo. Cuando existe una conversión implícita, no se necesita conversión para tratar el tipo como otro tipo. Por lo tanto, decir "conversión implícita" en realidad no tiene sentido (excepto potencialmente en las pocas situaciones como las que menciona Eric en las que se agrega un operador de transmisión sin que el desarrollador lo escriba, como cuando se usa a foreach). Fuera de esas excepciones, las conversiones son explícitas por definición .
Servicio
5

De MSDN:

Conversiones explícitas (conversiones): las conversiones explícitas requieren un operador de conversión. La transmisión es necesaria cuando se puede perder información en la conversión o cuando es posible que la conversión no se realice correctamente por otros motivos. Los ejemplos típicos incluyen la conversión numérica a un tipo que tiene menos precisión o un rango más pequeño y la conversión de una instancia de clase base a una clase derivada.

Considere el siguiente ejemplo:

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

Y también:

Un reparto es una forma de informar explícitamente al compilador que tiene la intención de realizar la conversión y que sabe que podría producirse una pérdida de datos.

Puede usar System.Convertclass cuando quiera convertir entre tipos no compatibles . La principal diferencia entre la conversión y la conversión es la compilación y el tiempo de ejecución . Las excepciones de conversión de tipos aparecen en tiempo de ejecución , es decir, un tipo de conversión que falla en tiempo de ejecución provocará InvalidCastExceptionque se lance un.


Conclusión: en la conversión le está diciendo al compilador que aes realmente tipo by, de ser así, el proyecto se construye sin errores como este ejemplo:

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

Pero en la conversión que está diciendo al compilador que hay una manera de crear un nuevo objeto a partir adel tipo b, por favor hacerlo y proyecto se basa sin ningún error, pero como he dicho si el tipo de conversión falla en tiempo de ejecución, se producirá una InvalidCastExceptionde ser arrojado .

Por ejemplo, el código siguiente nunca se compila porque el compilador detecta que no puede convertir una expresión de tipo DateTimea tipo int:

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

Pero este se compila con éxito:

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

Pero en el tiempo de ejecución obtendrá lo InvalidCastExceptionque dice:

Conversión no válida de 'DateTime' a 'Int32'.

Salah Akbari
fuente
4

El Convert.Doublemétodo en realidad solo llama internamente al Double.Parse(string)método.

Ni el Stringtipo ni el Doubletipo definen una conversión explícita / implícita entre los dos tipos, por lo que la conversión siempre fallará.

El Double.Parsemétodo observará cada carácter del stringy generará un valor numérico basado en los valores de los caracteres del string. Si alguno de los caracteres no es válido, el Parsemétodo falla (lo que hace que el Convert.Doublemétodo también falle).

Dan
fuente
1
¿Y en qué se diferencia esto de un elenco explícito?
3
Una transmisión explícita no mira cuál es el tipo de datos, solo mira los bytes. Un ejemplo sería convertir char x = '1' a un número entero, el número entero sería 49 porque el carácter '1' es # 49 en la tabla ascii
user1751547
@ user1751547 Entonces, ¿el usuario de a Convert.ToDouble()miraría más allá de los bytes y consideraría los datos?
@ user1751547 Creo que ese es el tipo de intuición que se requiere para responder correctamente a esta pregunta. Decir simplemente "no está definido" es un poco discutible.
Ant P
@ edmastermind29 Sí, miraría el tipo de entrada, y si fuera una cadena, pasaría por cada carácter, sabiendo que si el valor ascii del char es 49, entonces es el carácter '1' y lo convierte correctamente
user1751547
3

En su ejemplo, está intentando convertir una cadena en un doble (tipo no integral).

Se requiere una conversión explícita para que funcione.

Y debo señalar que podría haber usado en Convert.ToDoublelugar de, Convert.ToInt64ya que puede perder las partes fraccionarias del valor doble cuando convierte a un int.

si su variable tiene el valor "5.25" varDouble habría sido 5.00 (pérdida de 0.25 debido a la conversión a Int64)

Para responder a su pregunta sobre la transmisión frente a la conversión.

Tu elenco (un elenco explícito) no cumple con los requisitos para un elenco explícito. el valor que está intentando convertir con el operador de conversión no es válido (es decir, no integral).

Visite esta página de MSDN para conocer las reglas de casting / conversiones

scartag
fuente
@ edmastermind29 He actualizado mi respuesta. Espero que responda a tu pregunta.
scartag
¿Cuáles son los requisitos para un elenco explícito ... en relación con mi pregunta? ¿Es en lo que respecta al valor "no integral"?
@ edmastermind29 Sí. si el valor que está intentando convertir a un tipo numérico no es numérico, la conversión no es válida. Se requiere una conversión.
scartag
3

El casting no implica ninguna conversión, es decir, la representación interna de un valor no se modifica. Ejemplo:

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.

Puedes convertir un doublea stringcomo este

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

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

Puede convertir stringa doubleen a de varias formas (aquí solo dos de ellas):

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

O la forma segura

string s = "5";
double d;
if (Double.TryParse(s, out d)) {
    Console.WriteLine("OK. Result = {0}", d);
} else {
    Console.WriteLine("oops!");
}
Olivier Jacot-Descombes
fuente
Convert.ToDouble()llamadas internasDouble.Parse() . ¿Me conviene usar Convert.ToDouble()over Double.Parse()o no y por qué?
Convert.ToDoubletiene muchas sobrecargas que aceptan diferentes tipos de entrada. La sobrecarga que acepta stringregresa 0.0si nullse pasa una cadena. Aparte de esto, no veo ninguna ventaja en su uso.
Olivier Jacot-Descombes
Entonces, ¿o ... o Double.Parse()tiene algo que ofrecer que debería considerar?
Double.Parse()es más directo que Convert.ToDouble(). Si está seguro de que su cadena contendrá un número válido, puede usarlo con seguridad; de lo contrario, le aconsejo que lo use Double.TryParse.
Olivier Jacot-Descombes
1
string variable = "5.00";     
double varDouble = (double)variable;

La conversión anterior simplemente no está permitida por el idioma. Aquí hay una lista de conversiones explícitas para tipos numéricos: http://msdn.microsoft.com/en-us/library/yht2cx7b.aspx Como puede ver, incluso no todos los tipos numéricos se pueden convertir a otro tipo numérico

Más información sobre el casting aquí

¿Y en qué se diferencia de Convert.ToDouble ()?

Cuando lanza un tipo, la estructura de datos no cambia. Bueno, en caso de conversión de valores numéricos, es posible que pierda algunos bits u obtenga algunos bits 0 adicionales. Pero todavía estás trabajando con un número. Solo está cambiando la cantidad de memoria que ocupa ese número. Eso es lo suficientemente seguro para que el compilador haga todo lo necesario.

Pero cuando intenta convertir una cadena en un número, no puede hacerlo porque no es suficiente para cambiar la cantidad de memoria ocupada por la variable. Por ejemplo, 5,00como cadena es una secuencia de "números": 53 (5) 46 (.) 48 (0) 48 (0) - eso es para ASCII, pero la cadena contendrá algo similar. Si el compilador solo tomará los primeros N (4 por doble? No estoy seguro) bytes de una cadena, esa pieza contendrá un número doble completamente diferente. Al mismo tiempo, Convert.ToDouble () ejecuta un algoritmo especial que tomará cada símbolo de una cadena, averiguará el dígito que representa y hará un número doble para usted, si la cadena representa un número. Lenguajes como PHP, en términos generales, llamarán Convert.ToDouble por usted en segundo plano. Pero C #, como un lenguaje escrito estáticamente, no lo hará por usted. Esto le permite estar seguro de que cualquier operación es segura de tipos y no obtendrá algo inesperado al hacer algo como:

double d = (double)"zzzz"
Viktor S.
fuente
@ edmastermind29 vea mi respuesta actualizada. Intenté explicarlo. La explicación está lejos de ser perfecta, pero supongamos que explica la diferencia.
Viktor S.
1

No se permite convertir una cadena a un doble como ese en C #, por lo que obtiene una excepción, debe convertir la cadena ( documento de MSDN que muestra rutas de conversión aceptables). Esto se debe simplemente a que una cadena no necesariamente va a contener datos numéricos, pero los diversos tipos numéricos sí (salvo valores nulos). A Convertejecutará un método que verificará la cadena para ver si se puede convertir en un valor numérico. Si puede, devolverá ese valor. Si no puede, lanzará una excepción.

Para convertirlo, tiene varias opciones. Usó el Convertmétodo en su pregunta, Parseque es muy similar a Convert, pero también debería mirar TryParse, que le permitiría hacer:

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.
}

Esto evita la posible excepción si lo intenta Converto Parseuna cadena no numérica.

Afilado
fuente
¿Me conviene utilizar un TryParseover Convertporque TryParsecomprueba si la conversión se realiza correctamente?
@ edmastermind29 Creo que sí. Convert lanzará una excepción si la conversión falla. TryParse devolverá un valor booleano, True si la conversión tiene éxito y False si falla.
Keen
1

double varDouble = (double)variableasume que variableya es un doble. Si variableno es un doble (es una cadena), esto fallará. double varDouble = Convert.ToDouble(variable)hace lo que dice: convierte. Si puede analizar o extraer un doble, variableentonces lo hará.

Segundo usando Double.Parseo Double.TryParseporque indica más claramente lo que se supone que está sucediendo. Está comenzando con una cadena y espera que sea convertible en un doble. Si tiene alguna duda, utilice TryParse.

Si variablees un argumento de método, cambie el tipo a doble. Haga que la persona que llama sea responsable de proporcionar el tipo correcto. De esa forma, el compilador hace el trabajo por usted.

Scott Hannen
fuente
-1

La diferencia más importante es que si se utiliza la conversión de tipos y la conversión falla (digamos que estamos convirtiendo un valor flotante muy grande en int) no se lanzará ninguna excepción y se mostrará el valor mínimo que puede contener un int. Pero en caso de usar Convert , se lanzará una excepción para tales escenarios.

Tom Hardy
fuente