Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Теоретический_курс.doc
Скачиваний:
36
Добавлен:
10.11.2019
Размер:
7.68 Mб
Скачать

3. Явные преобразования

Однако если преобразование не может быть выполнено без риска потери данных, для компилятора требуется, чтобы пользователь выполнил явное преобразование, которое называется приведением. Приведение является способом явно указать компилятору, что нужно сделать преобразование, и что известно, что может быть потеря данных. Для выполнения приведения заключите тип, в который производится приведение, в скобки перед преобразуемым значением или переменной. Следующая программа выполняет приведение типа double к типу int. Без приведения эта программа скомпилирована не будет:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace LC_Console

{

class Program

{

static void Main(string[] args)

{

double x = 1234.7;

int a;

a = (int)x;

Console.WriteLine(a);

Console.WriteLine("Для продолжения нажмите любую клавишу . . . ");

Console.ReadKey();

}

}

}

/* Выведет:

* 1234

* Для продолжения нажмите любую клавишу . . .

*/

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

Giraffe g = new Giraffe();

Animal a = g;

// Явное преобразование требуется перейти к производному типу.

// Примечание: Этот код откомпилируется, но выдает исключение во время выполнения,

// если с правой стороны объекта на самом деле не "жираф".

Giraffe g2 = (Giraffe)a;

Операция приведения между ссылочными типами не меняет тип времени выполнения базового объекта; меняется только тип значения, которое используется в качестве ссылки на этот объект.

3. Дополнительные сведения

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

int i;

float f;

i = 10;

f = i; // Присвоить целое значение переменной типа float

Если в одной операции присваивания смешиваются совместимые типы данных, то значение в правой части оператора присваивания автоматически преобразуется в тип, указанный в левой его части. Поэтому в приведенном выше фрагменте кода значение переменной i сначала преобразуется в тип float, а затем присваивается переменной f. Но вследствие строгого контроля типов далеко не все типы данных в С# оказываются полностью совместимыми, а следовательно, не все преобразования типов разрешены в неявном виде. Например, типы bool и int несовместимы. Правда, преобразование несовместимых типов все-таки может быть осуществлено путём приведения. Приведение типов, по существу, означает явное их преобразование.

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

Когда данные одного типа присваиваются переменной другого типа, неявное преобразование типов происходит автоматически при следующих условиях:

  • оба типа совместимы;

  • диапазон представления чисел целевого типа шире, чем у исходного типа.

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

Числовые типы, как целочисленные, так и с плавающей точкой, вполне совместимы друг с другом для выполнения расширяющих преобразований. Рассмотрим пример:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace LC_Console

{

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.WriteLine("Для продолжения нажмите любую клавишу . . . ");

Console.ReadKey();

}

static int Sum(int x, int y)

{

return x + y;

}

}

}

/* Выведет:

* 10 + 15 = 25

* Для продолжения нажмите любую клавишу . . .

*/

Обратим внимание на то, что метод Sum ожидает поступления двух параметров типа int. Тем не менее, в методе Main ему на самом деле передаются две переменных типа short. Хотя это может показаться несоответствием типов, программа будет компилироваться и выполняться без ошибок и возвращать в результате, как и ожидалось, значение 25.

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