Вопрос

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

Не удается преобразовать тип 'string' в 'int'

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

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

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

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

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

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

Это было полезно?

Решение

(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

https://dotnetfiddle.net/m3ddDQ

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top