Підрозділ 2.4
Типи даних
Систематизує основні типи даних C#: цілі числа, дробові типи, bool, char, string, object і var.
2.4. Типи даних
Як і в багатьох мовах програмування, у C# є власна система типів даних, яка використовується для створення змінних. Тип даних визначає внутрішнє представлення даних у пам'яті, діапазон значень, які може приймати змінна, і допустимі операції, які можна застосовувати над змінною. Саме тому, оголошуючи змінну, ми зобов'язані вказати її тип — компілятор використовує цю інформацію для перевірки коректності всіх операцій із цією змінною.

У мові C# є такі вбудовані базові типи даних:
bool
Тип bool зберігає логічне значення — true (істина) або false (хибність). Представлений системним типом System.Boolean.
byte
Тип byte зберігає ціле беззнакове число від 0 до 255 і займає 1 байт. Представлений системним типом System.Byte. Зручний для зберігання малих невід'ємних чисел — наприклад, значень компонентів кольору, відсотків, флагів.
sbyte
Тип sbyte (signed byte) зберігає ціле число зі знаком від -128 до 127 і займає 1 байт. Представлений системним типом System.SByte. Відрізняється від byte тим, що може зберігати від'ємні значення.
short
Тип short зберігає ціле число зі знаком від -32 768 до 32 767 і займає 2 байти. Представлений системним типом System.Int16.
ushort
Тип ushort (unsigned short) зберігає ціле беззнакове число від 0 до 65 535 і займає 2 байти. Представлений системним типом System.UInt16.
int
Тип int зберігає ціле число зі знаком від -2 147 483 648 до 2 147 483 647 і займає 4 байти. Представлений системним типом System.Int32. Це найпоширеніший цілочисленний тип у C# — за замовчуванням усі цілі літерали (наприклад, 42) мають саме тип int.
uint
Тип uint (unsigned int) зберігає ціле беззнакове число від 0 до 4 294 967 295 і займає 4 байти. Представлений системним типом System.UInt32. Для явного позначення uint-літерала використовується суфікс u або U.
long
Тип long зберігає ціле число зі знаком від -9 223 372 036 854 775 808 до 9 223 372 036 854 775 807 і займає 8 байт. Представлений системним типом System.Int64. Використовується тоді, коли діапазон int недостатній. Для явного позначення long-літерала — суфікс l або L.
ulong
Тип ulong (unsigned long) зберігає ціле беззнакове число від 0 до 18 446 744 073 709 551 615 і займає 8 байт. Представлений системним типом System.UInt64. Суфікс — ul або UL.
float
Тип float зберігає число з плаваючою точкою приблизно від -3.4 × 10³⁸ до 3.4 × 10³⁸ і займає 4 байти. Представлений системним типом System.Single. Забезпечує приблизно 7 значущих цифр. Для позначення float-літерала обов'язковий суфікс f або F.
double
Тип double зберігає число з плаваючою точкою приблизно від ±5.0 × 10⁻³²⁴ до ±1.7 × 10³⁰⁸ і займає 8 байт. Представлений системним типом System.Double. Забезпечує приблизно 15–16 значущих цифр. Це найпоширеніший тип для дробових чисел — за замовчуванням усі речові літерали (наприклад, 3.14) мають тип double.
decimal
Тип decimal зберігає десяткове дробове число з дуже високою точністю — 28–29 значущих цифр — і займає 16 байт. Представлений системним типом System.Decimal. Діапазон від ±1.0 × 10⁻²⁸ до ±7.9 × 10²⁸. Для позначення decimal-літерала обов'язковий суфікс m або M.
На відміну від float і double, тип decimal не має похибок округлення при роботі з десятковими дробами, тому він незамінний у фінансових розрахунках, де точність кожного знаку критична.
char
Тип char зберігає одиночний символ у кодуванні Unicode і займає 2 байти. Представлений системним типом System.Char. Символьні літерали беруться в одинарні лапки.
string
Тип string зберігає послідовність символів Unicode довільної довжини. Представлений системним типом System.String. Рядкові літерали беруться в подвійні лапки. На відміну від усіх попередніх типів, string є reference-типом — змінна зберігає не саме значення, а посилання на об'єкт у купі.
object
Тип object може зберігати значення будь-якого типу даних — як value-типів, так і reference-типів. Представлений системним типом System.Object, який є базовим класом для всіх типів і класів .NET. Займає 4 байти на 32-розрядній платформі та 8 байт — на 64-розрядній.
Хоча object здається зручним — «приймає все» — на практиці він використовується обережно, бо втрачається типобезпека і можливі накладні витрати при boxing/unboxing (про це детально у темі узагальнень).
Комплексний приклад
Визначимо кілька змінних різних типів і виведемо їх значення на консоль:
Використання суфіксів
При присвоєнні значень слід пам'ятати: всі речові літерали за замовчуванням мають тип double, а всі цілочисленні — тип int. Щоб явно вказати інший тип, використовуються суфікси:
Системні типи
Назва вбудованого типу — це скорочення відповідного системного типу .NET. Наприклад, int і System.Int32 є повністю еквівалентними:
Обидва записи абсолютно рівнозначні — компілятор сприймає їх однаково. На практиці зазвичай вживають скорочені псевдоніми (int, string, bool), оскільки вони стисліші і звичніші.
Неявна типізація
У C# можна не вказувати тип змінної явно, якщо компілятор може визначити його самостійно з виразу праворуч. Для цього замість назви типу вказується ключове слово var:
Оскільки за замовчуванням цілочисленні значення розглядаються як int, а речові — як double, то c отримає тип int, а d — тип double. Тип виводиться один раз при оголошенні і фіксується — надалі змінна поводиться точно так само, як якби тип був вказаний явно.
Неявно типізована змінна має кілька обмежень. По-перше, не можна спочатку оголосити змінну, а потім ініціалізувати — компілятор не знатиме, який тип вивести:
// Цей код працює:
int a;
a = 20;
// Цей код не працює — помилка компіляції:
var c;
c = 20;По-друге, не можна ініціалізувати var значенням null, оскільки null сам по собі не несе інформації про тип:
// Цей код не працює — помилка компіляції:
var c = null;