В чем разница между Convert.ToInt32 и (int)?
-
05-07-2019 - |
Вопрос
Следующий код выдает ошибку времени компиляции, например
Не удается преобразовать тип 'string' в 'int'
string name = Session["name1"].ToString();
int i = (int)name;
принимая во внимание, что приведенный ниже код компилируется и успешно выполняется:
string name = Session["name1"].ToString();
int i = Convert.ToInt32(name);
Я хотел бы знать:
Почему первый код генерирует ошибку во время компиляции?
В чем разница между двумя фрагментами кода?
Решение
(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)
использует половину даже для округления (округляет x.5 до ближайшего целого числа EVEN, что означаетifoo = Math.Round (foo)
). Таким образом, результат не только с точки зрения реализации, но и численно не одинаковый.
Другие советы
(эта строка относится к вопросу, который был объединен). Никогда не используйте (int) someString
- это никогда не сработает (и компилятор не позволит вам).
Однако int int.Parse (string)
и bool int.TryParse (string, out int)
(и их различные перегрузки) являются честной игрой.
Лично я в основном использую Convert
только когда имею дело с отражением, поэтому для меня выбор - Parse
и TryParse код>. Первый - это когда я ожидаю , что значение является допустимым целым числом, и в противном случае я хочу, чтобы оно выдало исключение. Во-вторых, когда я хочу проверить , является ли оно допустимым целым числом, я могу решить, что делать, если оно есть / нет.
Цитировать из этого статья Эрика Липперта :
Приведение означает две противоречивые вещи: " проверить, действительно ли этот объект относится к этому типу; бросить, если это не так " и "этот объект не относится к данному типу; найдите мне эквивалентное значение, которое принадлежит данному типу ".
То, что вы пытались сделать в 1.), это утверждение, что да, String - это Int. Но это утверждение не выполняется, поскольку String не является целым числом.
Причина 2.) успеха состоит в том, что Convert.ToInt32 () анализирует строку и возвращает int. Он все еще может потерпеть неудачу, например:
Convert.ToInt32("Hello");
Может привести к исключению аргумента.
Подводя итог, можно сказать, что преобразование строки в тип Int - это проблема структуры, а не нечто неявное в системе типов .Net.
Строка не может быть приведена к int через явное приведение. Он должен быть преобразован с использованием int.Parse
.
Convert.ToInt32 в основном обертывает этот метод:
public static int ToInt32(string value)
{
if (value == null)
{
return 0;
}
return int.Parse(value, CultureInfo.CurrentCulture);
}
Вы говорите об операции приведения C # в сравнении с утилитами преобразования .NET
- Уровень языка C # Кастинг использует круглые скобки - например(int) - и поддержка преобразования для него ограничена, полагаясь на неявную совместимость между типами или явно определенные инструкции разработчиком через операторы преобразования.
- В .NET Framework существует множество методов преобразования, например Система.Преобразовать, чтобы позволить преобразование между одинаковыми или разрозненными типами данных.
(Кастинг) синтаксис работает с числовыми типами данных, а также с "совместимыми" типами данных.Совместимые означают типы данных, для которых существует связь, установленная путем наследования (т. е.базовые / производные классы) или посредством реализации (т.е.интерфейсы).
Приведение также может работать между разрозненными типами данных, которые имеют операторы преобразования определенный.
Тот Самый Система.Преобразовать класс, с другой стороны, является одним из многих доступных механизмов для преобразования вещей в общем смысле;он содержит логику для преобразования между разрозненными известными типами данных, которые могут быть логически изменены из одной формы в другую.
Преобразование даже охватывает некоторые из тех же аспектов, что и приведение, позволяя выполнять преобразование между похожими типами данных.
Помните, что у языка C # есть свой собственный способ делать некоторые вещи.
И лежащий в основе .NET Framework имеет свой собственный способ выполнения задач, отличный от любого языка программирования.
(Иногда их намерения пересекаются.)
Рассматривайте приведение как функцию уровня языка C #, которая более ограничена по своей природе, и преобразование через систему.Класс Convert как один из многих доступных механизмов в .NET Framework для преобразования значений между различными типами.
В .NET нет преобразования по умолчанию из строки в int. Вы можете использовать int.Parse () или int.TryParse () для этого. Или, как вы уже сделали, вы можете использовать Convert.ToInt32 ().
Однако, в вашем примере, зачем делать ToString (), а затем вообще преобразовывать его обратно в int? Вы можете просто сохранить int в Session и получить его следующим образом:
int i = Session["name1"];
Просто короткое дополнение: в различных обстоятельствах (например, если вы конвертируете двойное число и т. д. в Int32), вы можете также захотеть беспокоиться о округлении при выборе между этими двумя. Convert.Int32 будет использовать округление банкира ( MSDN ); (int) будет просто урезать до целого числа.
1) C # - это типобезопасный язык, и он не позволяет вам присвоить строку числу
2) второй случай разбирает строку на новую переменную. В вашем случае, если Session - это сеанс ASP.NET, вам не нужно хранить там строку и преобразовывать ее обратно при извлечении
int iVal = 5;
Session[Name1] = 5;
int iVal1 = (int)Session[Name1];
Преобразовать.В INT32
return int.Parse(value, CultureInfo.CurrentCulture);
но (int) - это тип cast, поэтому (int) "2" не будет работать, поскольку вы не можете преобразовать string в int.но вы можете разобрать его как Convert.ToInt32 выполняет
Разница в том, что первый фрагмент - это приведение, а второй - преобразование. Хотя, я думаю, что, возможно, ошибка компилятора приводит к еще большей путанице из-за формулировок. Возможно, было бы лучше, если бы он сказал: «Невозможно привести тип« string »к« int ».
Это старое, но другое отличие состоит в том, что (int) не округляет числа в случае, если у вас есть двойной ej: 5.7, результат при использовании (int) будет 5, а если вы используете Convert.ToInt (), то число будет округлено до 6.
Это уже обсуждалось, но я хочу поделиться 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