Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лаб роб 0.doc
Скачиваний:
1
Добавлен:
14.11.2019
Размер:
169.98 Кб
Скачать

Явні перетворення

Існує велике число перетворень, які не можуть бути виконані неявно. При спробі зробити це компілятор видасть помилку. Не можна виконати неявно перетворення:

  • int в short – можлива втрата даних

  • int в uint – можлива втрата даних

  • uint в int – можлива втрата даних

  • float в int – буде втрачено все, що йде після десяткової крапки

  • будь-який числовий тип в char – будуть втрачені дані

  • decimal в будь-який числовий тип – десятковий тип внутрішньо влаштований по-іншому, ніж формати для цілих чисел і чисел з плаваючою комою

Проте ці перетворення можуть бути виконані явно з використанням приведення. Коли один тип приводиться до іншого, компілятор вимушений виконувати перетворення. Типовий синтаксис приведення:

long val = 3.0000;

int I = (int)val; // Допустиме перетворення. Максимум int дорівнює 2147483647.

Тип, до якого необхідно привести значення, указується в круглих дужках перед цим значенням.

Ця операція може бути небезпечною. Ви повинні точно знати, що робите. Навіть просте перетворення з long в int здатне викликати проблему, якщо значення змінної long більше, ніж максимально можливе значення int. Наприклад:

long val = 3000000000;

int I=(int) val; //Неправильное перетворення. Максимальне значення int дорівнює 2147483647.

В даному випадку не видається повідомлення про помилку, але і очікуваний результат не виходить. Якщо ми виконаємо цей код і виведемо на екран величину, яка міститься в I, то отримаємо: -1294967296.

Ніколи не слід покладатися на те, що перетворення типу дасть очікуваний результат. У С# є оператор checked, який можна використовувати для перевірки того, що операція не викликає переповнювання стека. За допомогою цього оператора можна з'ясувати, чи безпечне приведення типу, і змусити середовище виконання згенерувати виключення типу переповнення, якщо це не так:

long val = 3000000000;

int i = checked((int)val);

Пам'ятаючи про те, що будь-яке приведення типів є потенційно небезпечним, у програмі необхідно передбачити код, який оброблятиме можливі помилки приведення типів. Обробку виключень роблять за допомогою конструкції

try ... catch, яка є корисним і необхідним інструментом програміста.

За допомогою приведення типів можна виконувати самі різні перетворення, наприклад:

double price = 25.30;

int approximatePrice = (int)(price + 0.5);

В результаті буде отримана ціна, закруглена до найближчого долара. Проте при такому перетворенні втрачаються дані – все, що йде після десяткової крапки. Це неприпустимо, якщо планується використовувати величину вартості в подальших розрахунках. Проте корисно в тому випадку, якщо необхідно вивести на екран приблизний результат виконаного або частково виконаного розрахунку і ви не хочете лякати користувача великим числом знаків після коми.

Подивимося, що відбувається при перетворенні цілого без знаку в char:

ushort з = 43;

char symbol = (char)з;

Console.WriteLine(symbol);

На екран буде виведений символ, що має ASCII-код 43, тобто знак +. Можна проводити практично будь-які перетворення між числовими типами (включаючи char), якими б безглуздими вони не були, і вони працюватимуть. Наприклад, можна перетворити з decimal в char і навпаки:

decimal d = 65m;

char symbol = (char)d; // В результаті виходить буква А

char з = 'А';

decimal val = (decimal)з;// В результаті виходить число 65

Якщо значення, отримане в результаті приведення, не може поміститися в новий тип даних, перетворення все одно буде виконано, проте результат буде не таким, який очікується. Наприклад:

int I = -1;

char symbol = (char)I;

Це перетворення не повинне працювати, оскільки тип char не може набувати негативних значень. Проте помилки не відбувається, замість цього змінній symbol привоїти значення у вигляді знаку запитання (?).

Перетворення між типами за значенням не обмежується окремими змінними. Наприклад, можна перетворити елемент масиву типу double змінну структури типу int:

struct ItemDetails

{

public string Description;

public int ApproxPrice;

}

Double[] Prices = { 25.30, 26.20, 27.40, 30.00 };