Приведение типов

В программировании нередко значения переменных одного типа присваиваются переменным другого типа. Например, в приведенном ниже фрагменте кода целое значение типа int присваивается переменной с плавающей точкой типа float:
int  i;   float f;   i = 10;    f = i;

Если в одной операции присваивания смешиваются совместимые типы данных, то значение в правой части оператора присваивания автоматически преобразуется в тип, указанный в левой его части. Поэтому в приведенном выше фрагменте кода значение переменной i сначала преобразуется в тип float, а затем присваивается переменной f.

Зададимся вопросом, всегда ли возможно преобразование типов? Когда будут возникать сообщения об ошибках, как это повлияет на надежность разрабатываемых программ?

Вследствие строгого контроля типов далеко не все типы данных в C# оказываются полностью совместимыми, и, следовательно, не все преобразования типов разрешены в неявном виде.

Например, типы bool и int несовместимы. Правда, преобразование несовместимых типов все-таки может быть осуществлено путем приведения. Приведение типов, по существу, означает явное их преобразование.

Автоматическое преобразование типов

Когда данные одного типа присваиваются переменной другого типа, неявное преобразование типов происходит автоматически при следующих условиях:
1) оба типа совместимы;
2) диапазон представления чисел целевого типа шире, чем у исходного типа.
Если оба эти условия удовлетворяются, то происходит расширяющее преобразование.
Например, тип int достаточно крупный, чтобы вмещать в себя все действительные значения типа byte, а кроме того, оба типа, int и byte, являются совместимыми целочисленными типами, и поэтому для них вполне возможно неявное преобразование.
Числовые типы, как целочисленные, так и с плавающей точкой, вполне совместимы друг с другом для выполнения расширяющих преобразований.

Рассмотрим пример:

   
   using System;
   namespace ConsoleApplication1
   {  
      class Program
      {       
         static void Main(string[] args)
         {           
            short num1, num2;
            num1 =10;
            num2 =15;
            Console.WriteLine("{0} + {1} = {2}",num1,num2,Sum(num1,num2));
            Console.ReadLine();       
         }
         static int Sum(int x,int y) 
         {          
            return x + y; 
         }
      }
   }

Обратите внимание на то, что метод Sum() ожидает поступления двух параметров типа int. Тем не менее, в методе Main() ему на самом деле передаются две переменных типа short. Хотя это может показаться несоответствием типов, программа будет компилироваться и выполняться без ошибок и возвращать в результате, как и ожидалось, значение 25.
Причина, по которой компилятор будет считать данный код синтаксически корректным, связана с тем, что потеря данных здесь невозможна.
Поскольку максимальное значение (32767), которое может содержать тип short, вполне вписывается в рамки диапазона типа int (максимальное значение которого составляет 2147483647), компилятор будет неявным образом расширять каждую переменную типа short до типа int.
Формально термин «расширение» применяется для обозначения неявного восходящего приведения (upward cast), которое не приводит к потере данных.

Приведение несовместимых типов

Несмотря на всю полезность неявных преобразований типов, они неспособны удовлетворить все потребности в программировании, поскольку допускают лишь расширяющие преобразования совместимых типов. А во всех остальных случаях приходится обращаться к приведению типов. Приведение — это команда компилятору преобразовать результат вычисления выражения в указанный тип. А для этого требуется явное преобразование типов.

Ниже приведена общая форма приведения типов:
   (целевой_тип) выражение
Здесь целевой_тип обозначает тот тип, в который желательно преобразовать указанное выражение.

Если приведение типов приводит к сужающему преобразованию, то часть информации может быть потеряна. Например, в результате приведения типа long к типу int часть информации потеряется, если значение типа long окажется больше диапазона представления чисел для типа int, поскольку старшие разряды этого числового значения отбрасываются.
Когда же значение с плавающей точкой приводится к целочисленному типу, то в результате усечения теряется дробная часть этого числового значения. Так, если присвоить значение 1,23 целочисленной переменной, то в результате в ней останется лишь целая часть исходного числа (1), а дробная его часть (0,23) будет потеряна.

Давайте рассмотрим пример:

using System;
namespace ConsoleApplication1
{
   class Program
   {
      static void Main(string[] args)
      {
         int i1 =455,i2 =84500;
         decimal dec =7.98845m;
      // Приводим два числа типа int к типу short
         Console.WriteLine((short) i1);
         Console.WriteLine((short) i2);
      // Приводим число типа decimal к типу int
         Console.WriteLine((int) dec);
         Console.ReadLine();
      }
   }
}

Результатом работы данной программы будет:
455
18964
7

Обратите внимание, что переменная i1 корректно преобразовалась в тип short, т.к. ее значение входит в диапазон этого типа данных. Преобразование переменной dec в тип int вернуло целую часть этого числа. Преобразование переменной i2 вернуло значение переполнения 18964 (т.е. 84500 — 2*32768).

Роль класса System.Convert

В завершении темы преобразования типов данных стоит отметить, что в пространстве имен System имеется класс Convert, который тоже может применяться для расширения и сужения данных:
byte sum = Convert.ToByte(var1 + var2);

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

Однако, поскольку в C# есть операция явного преобразования, использование класса Convert для преобразования типов данных обычно является делом вкуса.

Другое полезное назначение методов класса Convert состоит в преобразовании строковой переменной в переменную числового типа. Я его использую достаточно часто! Ведь в консольном приложении возможен только ввод строк, и поскольку оператор Console.ReadLine() возвращает строку, то далее ее можно преобразовать в число, используя соответствующий метод, например:
int k = Convert.ToInt32(Console.ReadLine());
При невозможности преобразования строки в число возникает исключительная ситуация (далее исключение – exception), которое может быть также обработано.

 

Перейдем к изучению операторов языка С#, и начнем мы с арифметических операторов.


NEW: Наш Чат, в котором вы можете обсудить любые вопросы, идеи, поделиться опытом или связаться с администраторами.


Помощь проекту:

Понравилась статья? Поделиться с друзьями:
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
3 комментариев
Новые
Старые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии

Прошу прощения за мою дотошность, но опять вкралась опечатка, что заставляет «зависать» над текстом. В примере кода, главы «Автоматическое преобразование типов», вызывается метод staticintSum(int x,int y). Кажется пропущены пробелы и возможно это должно выглядеть так?:
static int Sum(intx,inty)

Важно: Вы можете поддержать проект и автора.
Важно: Вы можете поддержать проект и автора.
3
0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x
()
x