Pregunta

El siguiente código produce un error en tiempo de compilación como

No se puede convertir el tipo 'cadena' a 'int'

string name = Session["name1"].ToString();
int i = (int)name;

mientras que el siguiente código se compila y ejecuta correctamente:

string name = Session["name1"].ToString();
int i = Convert.ToInt32(name);

Me gustaría saber:

  1. ¿Por qué el primer código genera un error en tiempo de compilación?

  2. ¿Cuál es la diferencia entre los 2 fragmentos de código?

¿Fue útil?

Solución

(int) foo es simplemente una conversión al tipo Int32 ( int en C #). Esto está integrado en el CLR y requiere que foo sea una variable numérica (por ejemplo, float , long , etc.) En este sentido, es muy similar a un reparto en C.

Convert.ToInt32 está diseñado para ser una función de conversión general. Hace mucho más que lanzar; es decir, puede convertir de cualquier tipo primitivo a un int (más notablemente, al analizar una cadena ). Puede ver la lista completa de sobrecargas para este método aquí en MSDN .

Y como Stefan Steiger menciona en un comentario :

  

También, tenga en cuenta que a nivel numérico, (int) foo trunca foo ( ifoo = Math.Floor (foo) ), mientras que Convert.ToInt32 (foo) utiliza la mitad al redondeo uniforme (redondea x.5 al entero EVEN más cercano, que significa ifoo = Math.Round (foo) ). Por lo tanto, el resultado no es solo de implementación, sino también numéricamente no el mismo.

Otros consejos

(esta línea se relaciona con una pregunta que se fusionó) Nunca debes usar (int) someString , eso nunca funcionará (y el compilador no te dejará).

Sin embargo, int int.Parse (string) y bool int.TryParse (string, out int) (y sus diversas sobrecargas) son un juego justo.

Personalmente, principalmente solo uso Convert cuando trato con la reflexión, por lo que para mí la opción es Parse y TryParse . La primera es cuando espero que el valor sea un entero válido, y deseo que lance una excepción de lo contrario. La segunda es cuando quiero comprobar si es un número entero válido. Entonces puedo decidir qué hacer cuando es / no es.

Para citar este artículo de Eric Lippert :

  

Reparto significa dos cosas contradictorias: " compruebe si este objeto realmente es de este tipo, lance si no es " y " este objeto no es del tipo dado; encuéntrame un valor equivalente que pertenezca al tipo dado " ;.

Entonces, lo que intentabas hacer en 1.) es afirmar que sí, una cadena es un Int. Pero esa afirmación falla porque String no es un int.

La razón 2.) es exitosa porque Convert.ToInt32 () analiza la cadena y devuelve un int. Todavía puede fallar, por ejemplo:

Convert.ToInt32("Hello");

Resultaría en una excepción de argumento.

Para resumir, la conversión de una Cadena a una Int es una preocupación del marco, no algo implícito en el sistema de tipo .Net.

Una cadena no se puede convertir a un int mediante una conversión explícita. Debe convertirse utilizando int.Parse .

Convert.ToInt32 básicamente envuelve este método:

public static int ToInt32(string value)
{
    if (value == null)
    {
        return 0;
    }
    return int.Parse(value, CultureInfo.CurrentCulture);
}

Está hablando de una operación de conversión de C # vs .NET Utilidades de conversión

  • Nivel de idioma C # casting utiliza paréntesis, por ejemplo, (int) - y el soporte de conversión es limitado, confiando en la compatibilidad implícita entre los tipos, o instrucciones explícitas definidas por el desarrollador a través de operadores de conversión .
  • Existen muchos métodos de conversión en .NET Framework, por ejemplo, System.Convert , para permitir la conversión de entre tipos de datos iguales o dispares.
La sintaxis de

(conversión) funciona con tipos de datos numéricos, y también con " compatible " tipos de datos. Compatible significa tipos de datos para los cuales existe una relación establecida por herencia (es decir, clases base / derivadas) o por implementación (es decir, interfaces).

La conversión también puede funcionar entre tipos de datos dispares que tienen operadores de conversión definidos.

La clase System.Convert por otro lado es uno de los muchos mecanismos disponibles para convertir las cosas en el sentido general; contiene la lógica para convertir entre tipos de datos dispares y conocidos que se pueden cambiar lógicamente de una forma a otra.

La conversión cubre incluso el mismo terreno que la conversión al permitir la conversión entre tipos de datos similares.


Recuerde que el lenguaje C # tiene su propia manera de hacer algunas cosas.
Y el .NET Framework subyacente tiene su propia forma de hacer las cosas, aparte de cualquier lenguaje de programación.
(A veces se superponen en sus intenciones).

Piense en la conversión como una función de nivel de lenguaje C # que es de naturaleza más limitada, y la conversión a través de la clase System.Convert como uno de los muchos mecanismos disponibles en el marco .NET para convertir valores entre diferentes tipos.

No hay una conversión predeterminada de cadena a int en .NET. Puedes usar int.Parse () o int.TryParse () para hacer esto. O, como lo ha hecho, puede usar Convert.ToInt32 ().

Sin embargo, en su ejemplo, ¿por qué hacer un ToString () y luego volver a convertirlo en un int? Simplemente puede almacenar el int en Session y recuperarlo de la siguiente manera:

int i = Session["name1"];

Solo un breve extra: en diferentes circunstancias (por ejemplo, si está convirtiendo un doble, & amp; c en un Int32), es posible que también desee preocuparse por el redondeo al elegir entre estos dos. Convert.Int32 utilizará el redondeo bancario ( MSDN ); (int) simplemente se truncará a un entero.

1) C # es un lenguaje de tipo seguro y no te permite asignar una cadena a un número

2) el segundo caso analiza la cadena a una nueva variable.  En su caso, si la sesión es una sesión de ASP.NET, no tiene que almacenar la cadena allí y volver a convertirla al recuperar

int iVal = 5;
Session[Name1] = 5;
int iVal1 = (int)Session[Name1];

Convert.ToInt32

    return int.Parse(value, CultureInfo.CurrentCulture);

pero (int) es el tipo de conversión, por lo que (int) " 2 " no funcionará ya que no puedes lanzar una cadena a int. pero puedes analizarlo como Convert.ToInt32 do

La diferencia es que el primer fragmento es un lanzamiento y el segundo es un convertido. Aunque, creo que tal vez el error del compilador está proporcionando más confusión aquí debido a la redacción. Quizás sería mejor si dijera "No se puede convertir el tipo 'cadena' a 'int'.

Esto es antiguo, pero otra diferencia es que (int) no redondea los números en caso de que tenga un doble ej: 5.7 la salida que usa (int) será 5 y si usa Convert.ToInt () la el número se redondeará a 6.

Esto ya se discutió, pero quiero compartir un dotnetfiddle.

Si estás tratando con operaciones aritméticas y usando float, decimal, double, etc., deberías usar Convert.ToInt32 ().

using System;

public class Program
{
  public static void Main()
  {
    double cost = 49.501;
    Console.WriteLine(Convert.ToInt32(cost));
    Console.WriteLine((int)cost);
  }
}

Salida

50
49

https://dotnetfiddle.net/m3ddDQ

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top