→ Пошук по сайту       Увійти / Зареєструватися
Знання Мова програмування C#

Теорія типів і типізація в .NET

Обговоримо основи дисципліни типів у рамках. NET. Нагадаємо, що історія розвитку математичної формалізації для типових теорій викладена у вступній лекції, а основа теорії типів - у лекції 6.

Узагальнимо ті переваги, які відрізняють мови програмування і формальні теорії з типами.

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

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

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

Нагадаємо класифікацію систем типізації в мовах програмування.

Історично найбільш поширеною для мов програмування є сувора типізація. При такому формуванні системи типів в мові в будь-який момент існування будь-якого мовного об'єкта існує однозначна відповідність між об'єктом і його типом. Іншими словами, можна запрограмувати функцію, що визначає тип об'єкта, подібну раніше розглянутої нами функції typeof мови програмування C #. Строго типізований є класичні імперативні мови програмування Pascal, FORTRAN, PL / I та ін Відзначимо, що класичний варіант мови програмування C не є строго типізовані.

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

Ще одним важливим видом систем типізації мов програмування є поліморфна типізація. При такому підході припустимі вирази змінного типу (скажімо, функція упорядкування списку із заздалегідь невизначеним типом елементів).

 Ієрархія типів в. NET
Ри с. 18.1. Ієрархія типів в. NET 

Процедура контролю відповідності типів (type-checking) може бути реалізована як під час компіляції (compile time), тобто більш безпечним чином, так і під час виконання (run time) програми, що потенційно менш безпечно для програмного коду.

Досліджуємо особливості управління типами в системі типізації Common Type System технології Microsoft. NET.

З міркувань безпеки програмного коду Microsoft. NET типи Common Type System, так само, як об'єкти та класи, можуть використовуватися тільки після ініціалізації. При цьому необхідно враховувати особливості викликає методу, а також методів доступу get і зміни set.

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

Ієрархія типів у співвіднесенні з Microsoft. NET може бути представлена у формі тієї чи іншої сукупності (зокрема, у вигляді простору імен, файлу або збірки).

Як вже зазначалося, найбільш великими і важливими підкатегоріями ієрархічної системи типізації в Microsoft. NET є посилальні типи (reference type) і типи-значення (value type).

Розглянемо більш детально особливості реалізації посилальних типів і типів-значень в мові програмування C #.

Перш за все, типами-значеннями, на відміну від посилальних типів, містять безпосередньо об'єкти даних. Крім того, Типи-значення, не можуть бути порожніми (тобто приймати значення null).

Посилальні типи, на противагу типами-значеннями, містять не самі об'єкти, а лише посилання на них, і можуть приймати значення null.

В якості ілюстрації особливостей реалізації посилальних типів і типів-значень в мові програмування C # розглянемо наступний фрагмент програми мовою C #:

int i = 25;
string s = "John_Smith";
 

У першому рядку програми відбувається означення цілочисельної константи (тобто типу-значення), а в другій - рядковою (тобто типу-посилання). В результаті при виконанні першого рядка програми відбувається зв'язування зі значенням у пам'яті, а в другому - з посиланням, тобто покажчиком на область пам'яті.

Таблиця 18.1. Посилальні типи і типи-значень в .NET и C#.

типи-значень

Елементарні

int i; float x;

Перелічувані

enum State { Off, On }

Структурні

struct Point {int x,y;}

типи-посилання

Кореневі

object

Рядкові

string

Класи

class Foo: Bar, IFoo {...}

Інтерфейси

interface IFoo: IBar {...}

Масиви

string[] a = new string[10];

Делегати

delegate void Empty();


Проілюструємо ієрархію системи типів Common Type System програмного середовища Microsoft. NET прикладами з мови програмування C #, конкретизують підтипи для типів-значень і посилальних типів (див. табл. 18.1).

При цьому типи-значення розпадаються на такі підтипи:

  • елементарні (зокрема, цілочисельні і речові):
int i;
float x; 
  • перелічувані (зокрема, моделюють перемикачі):
enum State {Off, On} 
  • структурні (зокрема, моделюють точки на площині):
struct Point {int x, y;} 

У свою чергу, посилальні типи поділяються на такі підтипи:

  • кореневий підтип (покажчики на довільні об'єкти в ієрархії типів у Common Type System):
object 
  • рядкові (покажчики на рядки символів):
string 
  • класи (покажчики на об'єкти типу class):
class Foo: Bar, IFoo {...} 
  • інтерфейси (покажчики на об'єкти типу interface):
interface IFoo: IBar {...} 
  • масиви (зокрема, покажчики на рядки з 10 символів):
string [] a = new string [10]; 
  • делегати (удосконалені покажчики на функцію):
delegate void Empty ();
 

Ієрархія типів мови C #
Рис. 18.2. Ієрархія типів мови C # (фрагмент).       

Різноманіття типів можна розділити на зумовлені (заздалегідь задані системою програмування) і певні користувачем (user defined), див. рис. 18.2.

До останніх відносяться перерахування, масиви, класи, інтерфейси та делегати (покажчики на функцію).

Визначені типи діляться на посилальні типи (об'єкти і символьні рядки) та типами-значеннями (вбудовані - короткі і довгі цілі зі знаком і без знаку, а також числа з плаваючою точкою - з одинарною та подвійною точністю).

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

Неявні перетворення ініціюються Common Type System та здійснюються автоматично. При цьому результат неявного перетворення завжди успішний і не призводить до втрати точності.

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

Наведемо ряд прикладів перетворень типів на мові програмування C #:

int x = 25;
long y = x;
// Неявне
short z = (short) x;
// Явне
double d = 3.141592536;
float f = (float) d;
// Явне
long l = (long) d;
// Явне

Зауважимо, що система Common Type System середовища Microsoft. NET забезпечує безпечну типізацію, тобто гарантує відсутність побічних ефектів (переповнення оперативної пам'яті комп'ютера, некоректне перетворення типів і т.д.). Зауважимо також, що як явні, так і неявні перетворення типів можуть ініціюватися користувачем.

Як показали дослідження системи типізації Common Type System середовища проектування та реалізації програмних систем Microsoft. NET, ця ієрархія має значний об'єм.

З метою підвищення ефективності організації описи типів і маніпулювання ними в програмному забезпеченні, що працює під управлінням середовища Microsoft. NET, вводиться поняття простору імен (namespace).

Простором імен будемо називати механізм середовища Microsoft. NET, призначений для ідентифікації типів об'єктів мов програмування і середовища реалізації.

Значення механізму просторів імен полягає в тому, що з'являється можливість логічної структуризації системи типізації Common Type System в середовищі розробки додатків Microsoft. NET.

Описи просторів імен за аналогією з описами типів даних розміщуються у файлах.

Перелічимо основні властивості, якими характеризуються простору імен в середовищі Microsoft. NET:

  1.   простору імен можуть об'єднувати різні збірки;
  2.   простору імен можуть бути вкладеними один в одного;
  3.   між просторами імен та файлами не існує однозначної відповідності (тобто відображення, що переводить назву простору імен в ім'я файлу);
  4.   повне ім'я типу повинна містити всі необхідні простору імен.

Для ілюстрації застосування механізму просторів імен в середовищі програмування Microsoft. NET наведемо розгорнутий приклад опису просторів імен на мові програмування C #:

namespace N1
{
         // N1
         class C1
         {
               // N1.C1
               class C2
               {
                     // N1.C1.C2
               }
         }
         namespace N2
         {
               //N1.N2
               class C2
               {
                     // N1.N2.C2
               }
         }
}
 

Розглянутий приклад містить описи просторів двох імен: простору N1 з описом класів C1 і C2 і простору N2 з описом класу C2.

Зауважимо, що в коментарях до кожного рядка програми на мові C # наведені повні найменування просторів імен. Так, для звернення до класу C2, описаного в просторі імен N1, потрібно використовувати повне ім'я N1.C1.C2, а звернення до класу C2, описаного в просторі імен N2 - повне ім'я N1.N2.C2.

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

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

Виявляється, що неодмінне використання повних імен типів у середовищі програмування Microsoft. NET є надлишковим вимогою.

Для економії трудовитрат і щоб уникнути колізій позначень при розробці великих програмних систем в мові програмування C # передбачений оператор using, до розгляду якого ми й переходимо.

Щоб проілюструвати застосування механізму ліквідації колізії позначень типів у просторах назв середовища програмування Microsoft. NET за допомогою оператора using, наведемо розгорнутий приклад на мові програмування C #:

using N1;
C1 a;
// Ім'я N1 є неявним
N1.C1 b;
// Повне ім'я
C2 c;
// Помилка: ім'я C2 не визначено
N1.N2.C2 d;
// Один з (під) класів C2
C1.C2 e;
// Ще один з (під) класів C2
using C1 = N1.N2.C1;
using N2 = N1.N2;
C1 a;
// Відповідає імені N1.N2.C1
N2.C1 b;
// Відповідає імені N1.N2.C1 

Зауважимо, що оператор using дозволяє використовувати типи як з вказівкою повного імені, так і без нього, а також для вказівки альтернативних імен (alias).

Ще одним аспектом проектування і реалізації великих програмних комплексів під управлінням середовища Microsoft. NET є потенційна колізія імен типів у рамках масштабних проектів.

Для вирішення цієї проблеми в середовищі розробки програмного забезпечення Microsoft Visual Studio для кожного з проектів можуть бути вказані так звані посилання, кожна з яких ідентифікує унікальну збірку - самодостатню одиницю для компіляції і виконання в рамках програмного проекту.

Посилання передаються компілятору під час трансляції програми на тій чи іншій мові програмування під управлінням середовища Microsoft. NET за посиланням (при цьому використовується опція / r або / reference).

Скажімо, команда на компіляцію файлу HelloWorld з вихідним текстом програми на мові C # з посиланням на простір імен System.WinForms.dll буде мати вигляд:

csc HelloWorld.cs
/ Reference: System.WinForms.dll
 

Як видно з наведеного прикладу, механізм посилань реалізує ідентифікацію компонування для використання в проекті Програми.

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

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

Підводячи підсумки розгляду основних аспектів теорії типів і типізації в мовах програмування, можна зробити наступні висновки:

  1.  теорії з типами та мови програмування з типізацією мають значно вищу обчислювальну потужність, а, отже, більш високу теоретичну і прикладну значимість.
  2. технологічна платформа. NET забезпечує ряд безсумнівних додаткових переваг перед іншими відомими платформами щодо системи типів.

Зокрема, технологія. NET використовує централізовану, уніфіковану, інтегровану систему типізації Common Type System (CTS), загальну для всіх мов програмування, що реалізуються на даній платформі.

Крім того, в рамках технологічної платформи. NET забезпечується сувора, однозначна відповідність між примітивними типами мов програмування і базовими класами. NET. Більшість компіляторів для мов програмування, які реалізовані для платформи. NET, мають вбудовану підтримку примітивних типів.

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

загрузка...
Сторінки, близькі за змістом