В чем разница между Convert.ToInt32 и (int)?

Следующий код генерирует ошибку времени компиляции, например

Невозможно преобразовать тип 'string' в 'int'

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

тогда как код ниже компилируется и выполняется успешно:

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

Я хотел бы знать:

  • Почему первый код генерирует ошибку времени компиляции?

  • Какая разница между двумя фрагментами кода?

Ответ 1

(int)foo - это просто приведение к типу Int32 (int в С#). Это встроено в CLR и требует, чтобы foo была числовой переменной (например, float, long и т.д.). В этом смысле она очень похожа на приведение в C.

Convert.ToInt32 разработан, чтобы быть общей функцией преобразования. Это делает намного больше, чем кастинг; а именно, он может конвертировать из любого примитивного типа в тип int (в частности, анализ string). Вы можете увидеть полный список перегрузок для этого метода здесь на MSDN.

И как Стефан Штайгер упоминает в комментарии:

Также обратите внимание, что на числовом уровне (int) foo foo ifoo = Math.Floor(foo) foo (ifoo = Math.Floor(foo)), а Convert.ToInt32(foo) использует округление от половины до четного (округляет x.5 до ближайшего целого числа EVEN, что означает ifoo = Math.Round(foo)). Таким образом, результат не только с точки зрения реализации, но и численно не одинаков.

Ответ 2

(эта строка относится к вопросу, который был объединен). Вы никогда не должны использовать (int)someString - это никогда не будет работать (и компилятор не позволит вам).

Однако int int.Parse(string) и bool int.TryParse(string, out int) (и их различные перегрузки) являются честной игрой.

Лично я в основном использую Convert, когда имею дело с отражением, поэтому для меня выбор Parse и TryParse. Во-первых, когда я ожидаю значение как действительное целое число и хочу, чтобы оно выбрало исключение иначе. Во-вторых, когда я хочу проверять, если это допустимое целое число, я могу решить, что делать, когда оно/нет.

Ответ 3

Процитировать статья Эрика Липперта:

Cast означает две противоречивые вещи: "проверьте, действительно ли этот объект имеет этот тип, бросьте, если он не является" и "этот объект не относится к данному типу, найдите мне эквивалентное значение, принадлежащее данному типу".

То, что вы пытались сделать в 1.), утверждает, что да, String - это Int. Но это утверждение терпит неудачу, поскольку String не является int.

Причина 2.) выполняется успешно, потому что Convert.ToInt32() анализирует строку и возвращает int. Он все равно может потерпеть неудачу, например:

Convert.ToInt32("Hello");

Приведёт к исключению Argument.

Подводя итог, преобразование из String в Int - это проблема структуры, а не что-то неявное в системе типа .Net.

Ответ 4

Строка не может быть передана в int через явное литье. Он должен быть преобразован с помощью int.Parse.

Convert.ToInt32 в основном обертывает этот метод:

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

Ответ 5

Вы говорите о операции литья С# против .NET Conversion утилит

  • С# Уровень языка casting использует скобки - например. (int) - и поддержка преобразования для него ограничена, полагаясь на неявную совместимость между типами или явно определенные инструкции разработчика через операторы преобразования.
  • Многие методы преобразования существуют в .NET Framework, например. System.Convert, чтобы разрешить преобразование между одинаковыми или разрозненными типами данных.
Синтаксис

(Casting) работает с числовыми типами данных, а также с "совместимыми" типами данных. Совместимые типы данных, для которых существует взаимосвязь, установленная посредством наследования (например, базовые/производные классы) или посредством реализации (то есть интерфейсы).

Кастинг также может работать между разрозненными типами данных, которые определены

Ответ 6

1) С# является безопасным языком и не позволяет назначать строку номеру

2) второй случай анализирует строку на новую переменную.  В вашем случае, если сеанс является сеансом ASP.NET, вам не нужно хранить строку там и преобразовывать ее при извлечении

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

Ответ 7

В .NET нет значения по умолчанию из строки в int. Для этого вы можете использовать int.Parse() или int.TryParse(). Или, как вы это сделали, вы можете использовать Convert.ToInt32().

Однако, в вашем примере, почему ToString(), а затем полностью преобразовать его в int? Вы можете просто сохранить int в сеансе и получить его следующим образом:

int i = Session["name1"];

Ответ 8

Достаточно кратковременно: в разных обстоятельствах (например, если вы конвертируете double, & c в Int32), вы также можете беспокоиться о округлении при выборе между этими двумя. Convert.Int32 будет использовать округление банкира (MSDN); (int) будет просто усекать до целого числа.

Ответ 9

Convert.ToInt32

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

но (int) - это тип, поэтому (int) "2" не будет работать, поскольку вы не можете отличить строку от int. но вы можете разобрать его, как Convert.ToInt32 do

Ответ 10

Разница в том, что первый фрагмент - это литой, а второй - конвертер. Хотя, я думаю, возможно, ошибка компилятора создает больше путаницы здесь из-за формулировки. Возможно, было бы лучше, если бы он сказал: "Нельзя использовать тип" string "для" int ".

Ответ 11

Это старое, но другое отличие состоит в том, что (int) не округляет числа в случае, если у вас есть двойной ej: 5.7. ouput using (int) будет равен 5, и если вы используете Convert.ToInt(), число будет округлено до 6.

Ответ 12

Это уже обсуждалось, но я хочу поделиться dotnetfiddle.

Если вы имеете дело с арифметическими операциями и используете float, decimal, double и так далее, вам лучше использовать Convert.ToInt32().

using System;

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

Выход

50
49

https://dotnetfiddle.net/m3ddDQ