В чем разница между Convert.ToInt32 и (int)? - PullRequest
49 голосов
/ 22 октября 2009

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

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

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

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

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

Хотелось бы знать:

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

  2. В чем разница между двумя фрагментами кода?

Ответы [ 12 ]

62 голосов
/ 22 октября 2009

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

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

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

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

18 голосов
/ 27 февраля 2011

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

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

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

5 голосов
/ 22 октября 2009

Цитировать из этой статьи Эрика Липперта :

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

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

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

Convert.ToInt32("Hello");

Может привести к исключению аргумента.

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

4 голосов
/ 22 октября 2009

Вы говорите об операции приведения C # к утилитам преобразования .NET

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

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

Приведение может также работать между разнородными типами данных, для которых определены операторы преобразования .

Класс System.Convert , с другой стороны, является одним из многих доступных механизмов для преобразования вещей в общем смысле; он содержит логику для преобразования между разнородными, известными типами данных, которые можно логически изменять из одной формы в другую.

Преобразование даже охватывает некоторые из тех же оснований, что и приведение, позволяя преобразование между похожими типами данных.


Помните, что язык C # имеет свой собственный способ выполнения некоторых действий.
А базовый .NET Framework имеет свой собственный способ работы, не говоря уже о любом языке программирования.
(Иногда они совпадают в своих намерениях.)

Думайте о приведении как о функции уровня языка C #, которая более ограничена по своей природе, и о преобразовании через класс System.Convert в качестве одного из многих доступных механизмов в .NET Framework для преобразования значений между различными видами.

4 голосов
/ 22 октября 2009

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

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

public static int ToInt32(string value)
{
    if (value == null)
    {
        return 0;
    }
    return int.Parse(value, CultureInfo.CurrentCulture);
}
1 голос
/ 25 июля 2011

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

1 голос
/ 22 октября 2009

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

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

int i = Session["name1"];
1 голос
/ 22 октября 2009

1) C # - это типобезопасный язык, и он не позволяет вам присвоить строку номеру

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

int iVal = 5;
Session[Name1] = 5;
int iVal1 = (int)Session[Name1];
0 голосов
/ 07 июня 2019

Это уже обсуждалось, но я хочу поделиться 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

0 голосов
/ 27 мая 2017

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...