Упражнение. Изучение приведения и преобразования типов данных
- 30 мин
Существует несколько методов преобразования типов данных. Выбранный метод зависит от ответа на два важных вопроса:
- Возможно ли, что попытка изменить тип данных значения вызовет исключение во время выполнения?
- Возможно ли, что попытка изменить тип данных значения приведет к потере информации?
В этом упражнении вы работаете над этими вопросами, последствиями их ответов и какой метод следует использовать, когда необходимо изменить тип данных.
Подготовка среды программирования
Этот модуль включает практические действия, которые помогут вам в процессе создания и выполнения демонстрационного кода. Рекомендуется выполнить эти действия с помощью Visual Studio Code в качестве среды разработки. Использование Visual Studio Code для этих действий помогает вам стать более удобным написанием и запуском кода в среде разработчика, которая используется специалистами по всему миру.
Примечание.
Если вы выполнили другие модули Microsoft Learn в этой серии C#, возможно, вы уже создали папку проекта для примеров кода. Если это так, можно пропустить следующий раздел шагов и удалить код в Program.cs файле, используемом для предыдущего упражнения.
Примечание.
Примеры кода в этом упражнении предназначены на основе параметров языка и региональных параметров en-US и используют период (.) в качестве десятичного разделителя. Создание и выполнение кода с параметром языка и региональных параметров, использующими разные десятичные разделители (например, запятую ,), могут дать непредвиденные результаты или ошибки. Чтобы устранить эту проблему, замените десятичные разделители периодов в примерах кода локальным разделителем десятичных разрядов (например ,).
Кроме того, чтобы запустить программу с помощью параметра языка и региональных параметров en-US, добавьте следующий код в верхнюю часть программы: using System.Globalization; и после добавления других using инструкций CultureInfo.CurrentCulture = new CultureInfo("en-US");.
Откройте Visual Studio Code.
Для открытия Visual Studio Code можно использовать меню Windows (или эквивалентный ресурс для другой ОС).
В меню "Файл Visual Studio Code" выберите "Открыть папку".
В диалоговом окне "Открыть папку " перейдите в папку "Рабочий стол Windows".
Если у вас есть другое расположение папки, в котором хранятся проекты кода, вместо этого можно использовать это расположение папки. Для этого обучения важно иметь расположение, которое легко найти и помнить.
В диалоговом окне "Открыть папку " выберите "Выбрать папку".
Если появится диалоговое окно безопасности с запросом доверия авторам, нажмите кнопку "Да".
В меню Терминала Visual Studio Code выберите Новый терминал.
Обратите внимание, что в командной строке на панели терминала отображается путь к папке текущей папки. Например:
C:\Users\someuser\Desktop>Чтобы создать консольное приложение в указанной папке, введите командную строку терминала и
dotnet new console -o ./CsharpProjects/TestProjectнажмите клавишу ВВОД.Эта команда .NET CLI использует шаблон программы .NET для создания проекта консольного приложения C# в указанном расположении папки. Команда создает папки CsharpProjects и TestProject для вас и использует TestProject в качестве имени
.csprojфайла.На панели обозревателя разверните папку CsharpProjects .
Вы увидите папку TestProject и два файла, файл программы C# с именем Program.cs и файл проекта C# с именем TestProject.csproj.
На панели обозревателя для просмотра файла кода на панели редактора выберите Program.cs.
Удалите существующие строки кода.
Этот консольный проект C# используется для создания, сборки и запуска примеров кода во время этого модуля.
Закройте панель терминала.
Вопрос. Возможно ли, что попытка изменить тип данных значения вызовет исключение во время выполнения?
Компилятор C# пытается разместить код, но не компилирует операции, которые могут привести к исключению. Когда вы понимаете основную озабоченность компилятора C#, понять, почему он работает определенным способом проще.
Написание кода, который пытается добавить int и сохранить string результат в int
Убедитесь, что на панели редактора открыт и Program.cs visual Studio Code.
Примечание.
Program.cs должно быть пустым. Если нет, выберите и удалите все строки кода.
Введите следующий код в редактор Visual Studio Code:
int first = 2; string second = "4"; int result = first + second; Console.WriteLine(result);Здесь вы пытаетесь добавить значения
2и4. Значение4имеет типstring. Будет ли этот код работать?В меню "Файл Visual Studio Code" нажмите кнопку "Сохранить".
Перед созданием или выполнением кода необходимо сохранить файл Program.cs.
На панели обозревателя откройте терминал в папке TestProject, щелкните правой кнопкой мыши TestProject и выберите "Открыть в интегрированном терминале".
Панель терминала должна открыться и должна содержать командную строку, показывающую, что терминал открыт для расположения папки TestProject.
В командной строке терминала, чтобы запустить код, введите
dotnet runи нажмите клавишу ВВОД.Вы должны увидеть следующие приблизительные выходные данные
C:\Users\someuser\Desktop\csharpprojects\TestProject\Program.cs(3,14): error CS0029: Cannot implicitly convert type 'string' to 'int'Примечание.
Если появится сообщение "Не удалось найти проект для запуска", убедитесь, что в командной строке терминала отображается ожидаемое расположение папки TestProject. Например:
C:\Users\someuser\Desktop\csharpprojects\TestProject>Минуту, чтобы рассмотреть причину, почему компилятору не удалось запустить первый пример кода.
Важная часть сообщения
(3,14): error CS0029: Cannot implicitly convert type 'string' to 'int'об ошибке сообщает, что проблема связана с использованиемstringтипа данных.Но почему компилятор C# не может просто обработать ошибку? В конце концов, можно сделать противоположное, чтобы сцепить число с
stringи сохранить его в строковой переменной. Здесь вы измените тип данных переменнойresultнаintstring.Обновите код в редакторе Visual Studio Code следующим образом:
int first = 2; string second = "4"; string result = first + second; Console.WriteLine(result);Сохраните файл кода и используйте Visual Studio Code для запуска кода.
Вы должны наблюдать следующие выходные данные:
24Выходные данные математически неверны, но завершены путем объединения значений в виде символов "2" и "4".
Рассмотрим, еще раз, первый пример кода, в котором
resultпеременная имеет типint. Код с сообщением об ошибке.int first = 2; string second = "4"; int result = first + second; Console.WriteLine(result);Почему компилятор C# не может выяснить, что вы хотите рассматривать переменную
second, содержащуюся4как число, а неstring?
Компиляторы делают безопасные преобразования
Для компилятора C# здесь кроется потенциальная проблема. Переменная second имеет тип string, и ей может быть присвоено другое значение, например "hello". Если бы компилятор C# попытался преобразовать "hello" в число, это привело бы к исключению во время выполнения. Чтобы избежать этой возможности, компилятор C# неявно выполняет преобразование из stringint вас.
С точки зрения компилятора C#, более безопасной операцией является преобразование int в string и выполнение объединения.
Если ваша цель заключается в сложении строковых значений, компилятор C# требует более явного управления процессом преобразования данных. Иными словами, вы должны приложить дополнительные усилия и принять надлежащие меры предосторожности на тот случай, если преобразование вызовет исключение.
Если необходимо изменить значение с исходного типа данных на новый тип данных, а изменение может привести к исключению во время выполнения, необходимо выполнить преобразование данных.
Преобразование данных можно выполнить одним из нескольких способов:
- использовать вспомогательный метод применительно к типу данных;
- использовать вспомогательный метод применительно к переменной;
-
ConvertИспользование методов класса
Ниже приведены некоторые примеры этих методов преобразования данных.
Вопрос. Возможно ли, что попытка изменить тип данных значения приведет к потере информации?
Удалите или используйте оператор
//строковый комментарий, чтобы закомментировать код на предыдущем шаге упражнения и добавить следующий код:int myInt = 3; Console.WriteLine($"int: {myInt}"); decimal myDecimal = myInt; Console.WriteLine($"decimal: {myDecimal}");Сохраните файл кода и используйте Visual Studio Code для запуска кода.
Должен появиться следующий результат:
int: 3 decimal: 3Ключевой в этом примере является следующая строка кода:
decimal myDecimal = myInt;Так как любое значение типа
intлегко помещается вdecimal, компилятор выполняет преобразование.Термин расширения преобразования означает, что вы пытаетесь преобразовать значение из типа данных, которое может содержать меньше информации в тип данных, который может содержать дополнительные сведения. В этом случае значение, хранящееся в переменной типа, преобразованное в переменную типа
intdecimal, не теряет сведения.Когда вы знаете, что выполняете расширяющее преобразование, вы можете полагаться на неявное преобразование. Компилятор обрабатывает неявные преобразования.
Выполнение приведения
Удалите или используйте оператор
//строковый комментарий, чтобы закомментировать код на предыдущем шаге упражнения и добавить следующий код:decimal myDecimal = 3.14m; Console.WriteLine($"decimal: {myDecimal}"); int myInt = (int)myDecimal; Console.WriteLine($"int: {myInt}");Чтобы выполнить приведение, используйте оператор
()приведения для окружения типа данных, а затем поместите его рядом с переменной, которую необходимо преобразовать (например:(int)myDecimal). Вы выполняете явное преобразование в определенныйСохраните файл кода и используйте Visual Studio Code для запуска кода.
Должен появиться следующий результат:
decimal: 3.14 int: 3Ключевой в этом примере является следующая строка кода:
int myInt = (int)myDecimal;Переменная
myDecimalсодержит значение, которое имеет точность после десятичной запятой. Добавив инструкцию(int)приведения, вы говорите компилятору C# о том, что вы понимаете, что это возможно, вы потеряете эту точность, и в этой ситуации это нормально. Вы сообщаете компилятору, что вы выполняете преднамеренное преобразование, явное преобразование.
Определите, является ли преобразование "расширением" или "сужающим преобразованием"
Термин сужения преобразования означает, что вы пытаетесь преобразовать значение из типа данных, которое может содержать больше информации в тип данных, который может содержать меньше информации. В этом случае часть данных может быть утеряна, например, может снизиться точность (то есть число разрядов после десятичной запятой). Пример преобразования значения, хранящегося в переменной типа decimal , в переменную типа int. Если вы печатаете два значения, возможно, вы заметите потерю информации.
Если вы знаете, что выполняете сужающее преобразование, необходимо выполнить приведение. Таким образом вы сообщаете компилятору C#, что знаете о возможном снижении точности и допускаете его.
Если вы не уверены, потеряете ли данные в преобразовании, напишите код для выполнения преобразования двумя разными способами и наблюдайте за изменениями. Разработчики часто пишут небольшие тесты, чтобы лучше понять поведение, как показано в следующем примере.
Удалите или используйте оператор
//строковый комментарий, чтобы закомментировать код на предыдущем шаге упражнения и добавить следующий код:decimal myDecimal = 1.23456789m; float myFloat = (float)myDecimal; Console.WriteLine($"Decimal: {myDecimal}"); Console.WriteLine($"Float : {myFloat}");Сохраните файл кода и используйте Visual Studio Code для запуска кода.
Должен отобразиться примерно такой результат:
Decimal: 1.23456789 Float : 1.2345679Вы можете наблюдать за выводом, что приведение в объект
decimalfloatявляется сужающим преобразованием, так как вы теряете точность.
Выполнение преобразований данных
Ранее было указано, что изменение значения одного типа данных в другой может привести к исключению среды выполнения, и необходимо выполнить преобразование данных. Для преобразования данных можно использовать три метода.
- использовать вспомогательный метод применительно к переменной;
- использовать вспомогательный метод применительно к типу данных;
-
ConvertИспользование методов класса
Использование ToString() для преобразования числа в string
У переменной любого типа данных есть метод ToString(). Выполняемые методом ToString() действия зависят от его реализации для конкретного типа. Однако для большинства примитивных типов он осуществляет расширяющее преобразование. Хотя это не обязательно (так как в большинстве случаев можно полагаться на неявное преобразование) он может взаимодействовать с другими разработчиками, которые вы понимаете, что вы делаете, и это намеренно.
Ниже представлен простой пример использования метода ToString() для явного преобразования значений типа int в string.
Удалите или используйте оператор
//строковый комментарий, чтобы закомментировать код на предыдущем шаге упражнения и добавить следующий код:int first = 5; int second = 7; string message = first.ToString() + second.ToString(); Console.WriteLine(message);Сохраните файл кода и используйте Visual Studio Code для запуска кода. При запуске кода выходные данные должны отобразить объединение двух значений:
57
Преобразование в string вспомогательный intParse() метод
Большинство числовых типов данных имеют Parse() метод, который преобразует строку в заданный тип данных. В этом случае метод используется Parse() для преобразования двух строк в int значения, а затем их вместе.
Удалите или используйте оператор
//строковый комментарий, чтобы закомментировать код на предыдущем шаге упражнения и добавить следующий код:string first = "5"; string second = "7"; int sum = int.Parse(first) + int.Parse(second); Console.WriteLine(sum);Сохраните файл кода и используйте Visual Studio Code для запуска кода. При запуске кода выходные данные должны отобразить сумму двух значений:
12Попробуйте обнаружить потенциальную проблему с предыдущим примером кода? Что если любой из переменных
firstилиsecondбудет присвоено значение, которое нельзя преобразовать вint? Исключение создается во время выполнения. Компилятор И среда выполнения C# ожидает, что вы планируете заранее и предотвратить "незаконные" преобразования. Исключение среды выполнения можно уменьшить несколькими способами.Самый простой способ устранить эту ситуацию заключается в использовании
TryParse(), которая является лучшейParse()версией метода.
Преобразование в stringint класс с помощью Convert
Класс Convert имеет множество вспомогательных методов для преобразования значения из одного типа в другой. В следующем примере кода вы преобразуете пару строк в значения типа int.
Удалите или используйте оператор
//строковый комментарий, чтобы закомментировать код на предыдущем шаге упражнения и добавить следующий код:string value1 = "5"; string value2 = "7"; int result = Convert.ToInt32(value1) * Convert.ToInt32(value2); Console.WriteLine(result);Сохраните файл кода и используйте Visual Studio Code для запуска кода.
Должен появиться следующий результат:
35Примечание.
Почему метод называется
ToInt32()? Почему неToInt()?System.Int32— это имя базового типа данных в библиотеке классов .NET, с которым в языке программирования C# сопоставлено ключевое словоint. Поскольку классConvertтакже входит в библиотеку классов .NET, он вызывается по полному имени, а не по имени в C#. Типы данных и классы, определенные в библиотеке классов .NET, могут совместно использоваться различными языками .NET, такими как Visual Basic, F#, IronPython и другими.Метод
ToInt32()имеет 19 перегруженных версий, что позволяет принимать практически каждый тип данных.вы использовали
Convert.ToInt32()метод со строкой здесь, но, вероятно, следует использоватьTryParse(), когда это возможно.Итак, когда следует использовать
Convertкласс? КлассConvertлучше всего преобразовывать дробные числа в целые числа (int), так как он округляет способ ожидания.
Сравнение приведения и преобразования в объект decimalint
В приведенном ниже примере показано, что происходит при попытке приведения значения типа decimal к int (сужающее преобразование) и при преобразовании того же значения типа Convert.ToInt32() в decimal с помощью метода int.
Удалите или используйте оператор
//строковый комментарий, чтобы закомментировать код на предыдущем шаге упражнения и добавить следующий код:int value = (int)1.5m; // casting truncates Console.WriteLine(value); int value2 = Convert.ToInt32(1.5m); // converting rounds up Console.WriteLine(value2);Сохраните файл кода и используйте Visual Studio Code для запуска кода.
Должен появиться следующий результат:
1 2
Приведение усечения и преобразование округления
При приведении int value = (int)1.5m;значение с плавающей запятой усечено 1таким образом, что результат означает, что значение после десятичного разряда игнорируется полностью. Можно изменить литерал с плавающей запятой 1.999m и результат приведения будет одинаковым.
При преобразовании с помощью Convert.ToInt32()литерального значения с плавающей запятой округляется до 2. Если вы изменили литеральное значение 1.499mна , оно будет округлено до 1.
Кратко
Вы рассмотрели несколько важных концепций преобразования и приведения данных:
- Предотвращение ошибки среды выполнения при преобразовании данных
- Выполнение явного приведения, чтобы сообщить компилятору, что вы понимаете риск потери данных
- Использование компилятора для выполнения неявного приведения при выполнении расширения преобразования
-
()Используйте оператор приведения и тип данных для выполнения приведения (например,(int)myDecimal) -
ConvertИспользуйте класс, когда вы хотите выполнить сужение преобразования, но хотите выполнить округление, а не усечение информации
Проверьте свои знания
Обратная связь
Были ли сведения на этой странице полезными?
Нет
Нужна помощь с этой темой?
Хотите попробовать использовать Ask Learn для уточнения или руководства по этой теме?