3569

Типи даних C#

Лекция

Информатика, кибернетика и программирование

Типи даних C# Цей розділ присвячений універсальній системі типів .NET Common Type System (CTS), яка знаходиться в центрі Microsoft .NET Framework. CTS визначає не тільки всі типи, але і правила, яким Common Language Runtime (CLR) слідує відносно ого...

Украинкский

2012-11-03

88.5 KB

28 чел.

Типи даних C#

Цей розділ присвячений універсальній системі типів .NET Common Type System (CTS), яка знаходиться в центрі Microsoft .NET Framework. CTS визначає не тільки всі типи, але і правила, яким Common Language Runtime (CLR) слідує відносно оголошення і використання цих типів застосуваннями (так деколи називають програми). Ви познайомитеся з типами, доступними розробникам на С#, і дізнаєтеся про особливості їх застосування в програмах на С#. Ми почнемо з вивчення концепції, згідно якої в .NET кожен програмний елемент є об'єктом. Далі ми розглянемо дві категорії типів: розмірні (value types) і посилальні (reference types). Ви також дізнаєтеся, як упаковка (boxing) забезпечує ефективну роботу повністю об'єктно-орієнтованої системи типів. На завершення ми розглянемо роботу приведення типів в С# і приступимо до вивчення просторів імен.

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

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

На щастя, в світі .NET і С# такої проблеми вже немає, оскільки в CTS будь-яка суть — об'єкт. Більш того, всі об'єкти побічно походять від єдиного базового класу, визначеного у складі CTS. Цей базовий клас «System.Object ».

Розмірні і посилальні типи

Перед розробниками CTS стояло завдання створення системи типів, де будь-яка суть була б об'єктом, але система типів при цьому працювала ефективно. Вони вирішили цю задачу, розділивши типи CTS на дві категорії: розмірні (value types) і посилальні (reference types). Як ви незабаром побачите, ці терміни відображають способи виділення пам'яті і внутрішнього функціонування змінних.

Розмірні типи

Якщо деяка змінна має розмірний тип, вона містить реальні дані. Отже, перше правило для розмірних типів таке: вони не можуть бути null. Нижче, наприклад, я на С# виділив пам'ять, створивши змінну типу System.Int32, який визначений в CTS. При цьому оголошенні відбувається не що інше, як виділення в стеку 32-розрядної області.

int i = 32;

Крім того, при присвоєнні значення у виділений простір поміщається 32-розрядне число.

У С# визначено декілька розмірних типів, включаючи перечислений (enumerators), структури (structures) і примітиви (primitives). Оголошуючи змінну одного з цих типів, ви кожного разу виділяєте в стеку деяке число байтів, що асоціюються з цим типом, і працюєте безпосередньо з виділеним масивом бітів. Крім того, коли ви передаєте змінну розмірного типу, передається значення змінної, а не посилання на лежачий в її основі об'єкт.

Посилальні типи

Посилання (якщо вона не рівна null) — це не просто адреса, яка, як ви вважаєте, може указувати (а може і не указувати) на певний об'єкт. Посилання завжди гарантовано указує об'єкт заданого типу, вже виділений в купі. Крім того, посилання може бути рівна null.

Нижче виділяється значення посилального типу (string), але при цьому «за кулісами» в купі виділяється значення і повертається посилання на нього:

string s = "Hello,World";

Як і у разі розмірних типів, в С# декілька типів визначено як посилальні: класи, масиви, делегати (delegates) і інтерфейси. Оголошуючи змінну одного з цих типів, ви кожного разу виділяєте в купі деяке асоційоване з цим типом число байт. Але замість того, щоб працювати з ними безпосередньо (як у разі розмірних типів), ви працюєте з посиланням на виділений об'єкт.

Упаковка і розпаковування

Як же ці різні категорії типів забезпечують ефективнішу роботу системи? Це робиться за допомогою упаковки (boxing). У простому випадку при упаковці розмірний тип перетвориться в посилальний. У зворотному випадку посилальний тип розпаковується (unbox) в розмірний.

Чудово в даній методиці те, що об'єкт лише тоді є об'єктом, коли це необхідно. Допустимо, ви оголошуєте змінну типу System.Int32. Для неї виділяється пам'ять в стеку. Ви можете передавати цю змінну будь-якому методу, визначеному як тип System, що приймає аргументи. Object, а також звертатися до будь-якого з її членів, до якого у вас є доступ. Тому ви сприймаєте і відчуваєте її як об'єкт. Але в реальності це всього 4 байти в стеку.

Тільки коли ви намагаєтеся використовувати цю змінну згідно правилам, певним інтерфейсом базового класу System.Object, система автоматично упаковує змінну, внаслідок чого вона стає посилальним типом і може бути використана так само, як будь-який об'єкт. Упаковка — це механізм, за допомогою якого в С# будь-яка суть може бути представлена у вигляді об'єкту. Це дозволяє уникнути витрат, неминучих в тому випадку, якщо б всяка суть насправді була об'єктом. Звернемося до прикладів:

int foo = 42; // Розмірний тип.

object bar = foo; // Змінна foo упакована в bar.

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

А зараз виконаємо явне приведення типів, щоб перетворити bar назад в розмірний тип:

int foo = 42; // Розмірний тип.

object bar = foo; // Змінна foo упакована в bar.

int foo2 = (int)bar; // Розпаковування і приведення до типу int.

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

Корінь всіх типів: System.Object. Всі типи походять від типу System.Object, що дозволяє гарантувати наявність у кожного типу мінімального набору функціональних можливостей. Всі типи отримують «безкоштовно» чотири відкриті методи (табл. 6.1).

Табл. 6.1. Відкриті методи типу System.Object.

Метод

Опис

bool Equals()

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

int GetHashCodeO

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

Type GetType()

Використовується з методами віддзеркалення для отримання інформації про тип даного об'єкту.

string ToString

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

Нижче описані захищені методи System.Objeci (табл. 6.2).

Табл. 6.2. Захищені методи типу System.Object.

Метод

Опис

void Finalize()

Викликається в період виконання для звільнення ресурсів перед збором сміття. Цей метод можна викликати, а можна і не робити цього. Тому не поміщайте в нього що підлягає виконання код. Це правило виливається в щось під назвою детерміноване завершення (deterministic finalization).

Object MemberwiseClone

Представляє обмежену копію (shallow сміттю) об'єкту. Під цим я розумію копію об'єкту, що містить посилання на інші об'єкти, але не копії цих об'єктів. Якщо ваші класи повинні підтримувати повну копію (deep сміттю), яка дійсно включає копії об'єктів, на які вона посилається, то вам потрібно реалізувати інтерфейс ICloneable і самому уручну проводити клонування або копіювання.

Типи і псевдоніми

Тоді як CTS відповідає за визначення типів, які можуть використовуватися в різних мовах .NET, для більшості мов було вирішено реалізувати псевдоніми для цих типів. Наприклад, 4-байтове.

Цілочисельне значення, представляється типом System.Int32, який визначений в CTS. У С# для цього типу визначений псевдонім int. Використання цих методик рівноцінне. Нижче приводиться список різних типів, визначених в CTS, і їх псевдонімів в С# (табл. 3).

Табл. 6.3. Типи, визначені в CTS, і їх псевдоніми.

Логічний тип

Ім'я типу (C#)

Системний тип

(CLR)

Значення

Розмір

Bool

System.Boolean

true, false

8 біт

Арифметичні цілочисельні типи

Ім'я типу

Системний тип

Діапазон

Розмір

Sbyte

System.SByte

- 128... …127

Знакове, 8 Біт

Byte

System.Byte

0... …255

Беззнакове, 8 Біт

Short

System.Short

- 32768 …32767

Знакове, 16 Біт

Ushort

System.UShort

0... …65535

Беззнакове, 16 Біт

Int

System.Int32

- 2,147,483,648…2,147,483,647

Знакове, 32 Біт

Uint

System.UInt32

0...4…4,294,967,295

Беззнакове, 32 Біт

Long

System.Int64

- 9,223,372,036,854,775,808 …

9,223,372,036,854,775,807

Знакове, 64 Біт

Ulong

System.UInt64

0...18…18,446,744,073,709,551,615

Беззнакове, 64 Біт

Арифметичний тип із плаваючою крапкою

Ім'я типу

Системний тип

Діапазон

Точність

Float

System.Single

- 3. 402823e38 … + 3...402823e38

7 цифр

Double

System.Double

- 1. 79769313486232e308... 1.79769313486232e308

15-16 цифр

Арифметичний тип з фіксованою крапкою

Ім'я типу

Системний тип

Діапазон

Точність

Decimal

System.Decimal

-79,228,162,514,264,337,593,543,950,335

79,228,162,514,264,337,593,543,950,335

28-29 значущих цифр

Символьні типи

Ім'я типу

Системний тип

Діапазон

Точність

Char

System.Char

U+0000 - U+ffff

16 біт Unicode символ

String

System.String

Рядок із символів Unicode

Об'єктний тип

Ім'я типу

Системний тип

Примітка

Object

System.Object

Прабатько всіх убудованих і користувальницьких типів

Простори імен

Простори імен (namespaces) використовуються в С#- додатках для визначення області видимості. Оголосивши простір імен, розробник може дати С#- додаткам ієрархічну структуру, засновану на семантично зв'язаних групах типів і інших (вкладених) просторах імен. У формуванні одного простору імен можуть брати участь декілька файлів початкового коду. Ця обставина дозволяє при компоновці єдиного простору імен з декількох класів визначати кожен клас у власному файлі початкового коду. Програміст, що використовує створені вами класи, дістане доступ до всіх класів в просторі імен через ключове слово using.

Ключове слово using

Іноді у вас може виникнути бажання використовувати для деякого типу повністю кваліфіковане ім'я у формі простір_імен. -тип. Нижче ми використовуємо об'єкт Console, що існує в просторі імен System.

class Usingl {

public static void Main()

{

System.Console.WriteLine("test"); } >

А якщо відомо, що об'єкт Console існує тільки в просторі імен System! Ключове слово using дозволяє задати порядок пошуку просторів імен. Отже, зустрівши некваліфікований тип, компілятор може звернутися до вказаного списку просторів імен для пошуку цього типу. У наступному прикладі розробникові не обов'язково кожного разу указувати ім'я простору імен (System), щоб компілятор міг знайти в нім об'єкт Console:

using System;

class Using2 {

public static void MAINQ

{

Console.WriteLine("test");

} }

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

Ім'я класу не можна задавати за допомогою ключового слова using. Тому такий код невірний:

using System.Console; // Неприпустимо!

class USINGS {

public static void Hain()

{

WriteLineC'tesf);

} }

Проте ви можете вийти з положення, використовуючи ключове слово using для створення псевдоніма:

using console = System.Console;

class Using4 {

public static void Main()

<

console. WriteLineC'tesf);

> }

Це дає особливо багато переваг, коли вкладені простори імен об'єднані з довгими іменами класів, що робить написання коду вельми утомливим заняттям.

Переваги використання CTS

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

Можливість взаємодії мов

CTS грає важливу роль в забезпеченні здібності до взаємодії мов, оскільки вона визначає набір типів, які повинен підтримувати компілятор .NET, щоб забезпечувати взаємодію з іншими мовами. Сама CTS визначена в специфікації CLS (Common Language Specification). CLS визначає єдиний набір правил для кожного компілятора .NET, гарантуючи, що кожен компілятор видаватиме код, що погоджено взаємодіє з CLR. Згідно вимогам CLS, компілятор повинен підтримувати деякі типи, визначені в CTS. Всі мови .NET використовують єдину систему типів. Це вигідно, оскільки гарантує безшовну взаємодію об'єктів і типів, що створюються на різних мовах. Завдяки цій комбінації CTS/CLS взаємодія програм на різних мовах — це вже не мрія програмістів, а реальність.

Безпека типів

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

  •  Кожне посилання на об'єкт типізується, як і об'єкт, на який вона посилається. CTS гарантує, що посилання завжди указує саме на те, на що вона повинна указувати.
  •  Оскільки CTS відстежує кожен тип в системі, систему не можна обдурити, видавши один тип за іншого. Очевидно, це особливо важливо для розподілених застосувань, де пріоритетом є захист.
  •  Кожен тип відповідає за визначення доступності своїх членів, задаючи модифікатор доступу. Це робиться для кожного члена окремо. Може бути заданий будь-який вид доступу (якщо член оголошений як public), доступ може бути обмежений довкола успадкованих класів (якщо член оголошений як protected) або зовсім заборонений (при оголошенні члена як private). Можна також вирішити доступ до члена тільки іншим типам у складі поточного компільованого модуля, якщо оголосити його як internal.

Підведемо підсумки

CTS (Common Type System) — важлива особливість .NET Framework. CTS визначає правила системи типів, яким застосування зобов'язані слідувати, щоб коректно працювати в CLR. Типи CTS діляться на посилальних і розмірних. Для визначення області видимості застосування можна використовувати простори імен. Серед вигод, CTS, що надаються, слід зазначити можливість взаємодії мов, ієрархію об'єктів з єдиним коренем і безпеку типів. У С# типи можуть бути перетворені за допомогою упаковки і розпаковування, а приведення типів дозволяє створювати сумісні типи, що мають сумісні характеристики і функціональність.


 

А также другие работы, которые могут Вас заинтересовать

54341. Культура Европы в XX - начале XXI вв.: противоречия и проблемы 28.21 KB
  Таким образом процесс подготовки и проведения такого учебного занятия как комбинированный урок увлекает студентов активизирует их достаточно свободно пользоваться простыми языковыми средствами в основных видах речевой деятельности: говорении аудировании чтении и письме. ФГОУ СПО Чебоксарский техникум строительства и городского хозяйства МЕТОДИЧЕСКАЯ КАРТА ЗАНЯТИЯ Дисциплина: Английский язык Группа: С41 Преподаватель: Бутакова Л. Тема занятия: Строительство зданий и сооружений Тип и вид занятия: комбинированный Цели занятия...
54342. Методические основы использования прикладного ПО на уроках в школе 111.5 KB
  Деление на группы производят либо по способностям либо случайным образом например по партам или по алфавиту. В этом случае как правило формируются разно уровневые группы в которых быстро определяются лидеры и аутсайдеры. Гузеев предложил различать группы выравнивания поддержки и развития. Группы выравнивания состоят из учащихся с различной успеваемостью и ориентированы на достижение всех ее участников обязательного уровня образования; группы поддержки однородны по успеваемости; в группах развития ученики более высокого уровня...
54343. Дмитриу Донской. Куликовская битва 83 KB
  Что позволило Дмитрию Ивановичу открыто выступить против монголотатар и разгромить их 12 октября 1350 года у московского удельного князя Ивана родился сын которого окрестили Дмитрием. Дмитрия Московского сумели получить для своего князя ярлык. Разведка великого князя донесла что Мамай собрав войско уже три недели ждал на Дону Ягайло Литовского.
54344. Сучасний урок - джерело творчості вчителя 2.78 MB
  €œТестові завдання з геометрії. клас із використанням тестуючого комплексу MIFTests. Кожен вчитель є справжнім керівником дитячого колективу діти визнають своїх педагогів за лідерів та активно співпрацюють із ними а це означає: вчитель має власний педагогічний імідж свій особливий педагогічний почерк він – конкурентоспроможний компетентний фахівець. МАТЕМАТИКА ТА ІТК У сучасному світі потреба в комп’ютерних технологіях постійно зростає – вони необхідні і вдома і на робочому місці. Систематичне використання...
54345. Комплекс игр и упражнений «Биоэнергопластика» в коррекционной работе с детьми-логопатами 717 KB
  Поражение верхней височной извилины приводит к тому что человек слышит слова но не понимает их смысла так как в зоне Вернике как в своеобразной картотеке хранятся все усвоенные человеком слова точнее их звуковые образы и он всю жизнь пользуется этой картотекой. Если произошло поражение этой зоны то хранящиеся там звуковые образы слов распадаются человек перестает понимать слова. При нормальном слухе он остается глухим к словам. Действительно левое полушарие отвечает: за движение правых конечностей и обеих рук за...
54346. Урок русского языка и литературного чтения 352 KB
  Планируемые результаты учебного предмета Русский язык общие на 4 года обучения Личностными результатами изучения русского языка в начальной школе являются: осознание языка как основного средства человеческого общения; восприятие русского языка как явление национальной культуры; понимание того что правильная устная и письменная речь является показателем индивидуальной культуры человека; способность к самооценке на основе наблюдения за собственной речью; способность к итоговому и пооперационному самоконтролю; ...
54347. Етапи розвязування задач за допомогою компютера 1.3 MB
  Для розвязання цих задач компютер озброєний найрізноманітнішим програмним забезпеченням, яке поділяється на чотири великих категорії: операційні системи, системні утиліти, системи програмування, прикладне програмне забезпечення.
54348. Інформаційно-комп’ютерні технології на уроках географії та природознавства 83.5 KB
  Вчителями природознавства опановано такі теми: Створення слайдових презентацій у середовищі програми MS Power Point Пошук та завантаження текстової звукової та відеоінформації з Інтернету Створення потокових презентацій відео кліпів у середовищі програми Movie Mker Створення та обробка графічної інформації засобами растрового графічного редактора dobe Photoshop. № п п Термін Тема заняття 1 Вересень Створення слайдових презентацій у середовищі програми MS Power Point. 3 Лютий Створення потокових презентацій відео кліпів у...
54349. Методика вивчення дробових чисел за курсом Математика у 5-6 класах 334 KB
  Організація самостійної діяльності учнів при вивченні дій ззвичайними дробами. ВСТУП Характеристика обовязкових результатів навчальних досягнень при вивченні дробових чисел Основною метою курсу математики 5-6 класів вважається: систематичний розвиток понять числа та вироблення вмінь усно та письмово робити арифметичні операції над числами формувати вміння переводити практичні задачі на мову математики підготовка учнів до вивчення курсів Алгебра€ та Геометрія€. Форми організації усного рахунку Добре розвинені у учнів навики усної...