C#. Категории (группы) типов данных. Значимые типы. Ссылочные типы. Базовые типы данных. Обзор




Категории (группы) типов данных в C#. Значимые типы. Ссылочные типы. Базовые типы данных. Обзор


Содержание


Поиск на других ресурсах:

1. Что такое тип данных в языке C#?

В языке C# (как и в любом другом языке) тип данных – это характеристика переменной (объекта), константы или литерала, которая определяет:

  • множество допустимых значений;
  • внутреннюю форму представления данных в компьютере;
  • множество операций, допустимых для данного типа.

 

2. Какие категории (группы) типов данных определены в языке C#?

Любой тип данных в языке программирования C# представлен классом или структурой. Соответственно все типы данных языка C# делятся на две категории (группы):

  • значимые типы или типы-значения (value-types). Типы-значения еще называют структурные типы или базовые типы. Значимые типы описываются структурами;
  • ссылочные типы (reference-types). Ссылочные типы описываются классами.

 

3. Какие отличия между типами-значениями и ссылочными типами?

Между типами-значениями (значимыми типами и ссылочными типами можно определить отличия по следующим признакам.

1. Способ сохранения объекта (переменной) в памяти компьютера.

Объекты (переменные) типов-значений размещаются в стеке полностью. Объекты типов-ссылок размещаются по следующему принципу:

  • в стеке размещается ссылка на данные объекта;
  • в «управляемой куче» (managed heap) непосредственно размещаются данные (поля) объекта. На эти данные указывает ссылка из стека.

2. Отличие в базовом типе.

Для значимых типов базовым типом является System.ValueType. Для ссылочных типов базовым типом может быть любой незапечатанный (не sealed) тип кроме System.ValueType.

3. Возможность быть унаследованным.

Значимые типы всегда запечатаны, а потому не могут быть унаследованными (быть базовыми для других). Типы-ссылки могут выступать базовыми (быть унаследованными) для других типов, если они не являются запечатанными (не обозначены как sealed).

4. Способ передачи параметров в функцию.

Переменные значимых типов передаются по значению. Это значит, что функции передается полная копия переменной-аргумента. В случае со ссылочными типами при передаче ссылки в функцию, по значению копируется только сама ссылка.

5. Переопределение метода System.Object.Finalize().

Типы-значения не нуждаются в финализации, поскольку никогда не размещаются в «управляемой куче» (managed heap) в отличие от типов-ссылок.

6. Время существования переменной.

Типы-значения прекращают свое существование когда выходят за рамки того контекста, в котором они определялись. Типы ссылки уничтожаются «сборщиком мусора» (garbage collector).

Общим для типов-значений и типов-ссылок является то, что для тех и других можно определять конструкторы.

 

4. Целесообразность применения каждой категории типов данных

Для каждой категории типов определены условия их применения. Если важным есть небольшой объем памяти и быстродействие, то более целесообразно применять значимые типы. Если для сохранения данных нужен большой объем памяти, то более целесообразно использовать ссылочные типы. Это связано с тем, что размер управляемой «кучи» больше за размера стека.

 

5. Понятие базового типа в .NET.

Базовые типы – это типы-значения, которые описываются структурами. В языке C# любому базовому типу соответствует объявление некоторой структуры, которая входит в состав платформы .NET.

Например. Типу float соответствует .NET структура System.Single; типу long соответствует .NET структура System.Int64.
Более детально об использовании базовых типов в C# описывается здесь.






 

6. Структура системы базовых типов в .NET

Все встроенные типы C# являются производными от класса Object. На рисунке 1  отображена часть структуры базовой системы типов языка C#. Как видно из рисунка, типы-значения унаследованы от класса ValueType, который унаследован от класса Object.

C#. Общая сокращенная иерархическая структура .NET типов

Рисунок 1. Общая сокращенная иерархическая структура .NET типов

 

7. Целочисленные базовые типы данных и их .NET эквиваленты

Таблица базовых целочисленных типов данных и структур, соответствующих этим типам, изображена на рисунке 2. Отображаются:

  • название типа;
  • название .NET структуры, которая соответствует этому типу;
  • наличие (отсутствие) знака числа;
  • диапазон допустимых значений, которые может принимать переменная данного типа.

 

C#. Целочисленные базовые типы данных и соответствующие им .NET структуры

Рисунок 2. Целочисленные базовые типы данных и соответствующие им .NET структуры

 

8. Типы данных для чисел с плавающей запятой и их .NET эквиваленты

На рисунке 3 изображены базовые типы данных для чисел с плавающей запятой а также их характеристики.

 

C#. Типы данных для чисел с плавающей точкой и соответствующие им .NET структуры

Рисунок 3. Типы данных для чисел с плавающей точкой и соответствующие им .NET структуры

 

9. Символьный тип данных char. Структура System.Char

Для представления символьной информации в языке C# используется базовый тип char. В .NET этому типу соответствует структура System.Char. Каждая переменная типа char представляет символ в формате Unicode. В этом формате каждый символ идентифицируется 21-битным скалярным значением, которое называется «code point» (кодовая точка). Такое представление соответствует кодовой форме UTF-16 в которой кодовая точка декодируется в одно или несколько 16-битных значений.

Структура System.Char, описывающая тип char, содержит:

  • 16-битное значение в диапазоне от 0x0000 до 0xFFFF;
  • набор методов для сравнения объектов типа char.

 

10. Логический тип данных bool. Структура System.Boolean

В базовой системе типов .NET логическому типу данных bool соответствует структура System.Boolean. Переменная типа bool может принимать одно из двух значений: true (истина) или false (ложь).

 

11. Применение операции присваивания = для типов-значений и ссылочных типов

Для типов-значений и ссылочных типов операция присваивания имеет свои особенности. Рассмотрим их на примере присваивания двух переменных.

1. Присваивание типов-значений

К типам-значениям принадлежат переменные базовых типов (int, double, char и другие), структурные переменные (struct) и перечисления (enum). В целом такие переменные есть производными от класса System.ValueType. При присваивании таких переменных вида

var1 = var2;

значение переменной var2 копируется в переменную var1. Таким образом, переменная var1 содержит копию переменной var2. Дальнейшее изменение значения одной переменной никак не повлияет на значение другой переменной.

2. Присваивание типов ссылок

К типам ссылок принадлежат типы, которые описываются классами. При присваивании переменных ссылочного типа, которыми являются экземпляры классов или объекты,

MyClass ref1;
MyClass ref2;
...
ref1 = ref2; // присваивание ссылок
...

значение ссылки ref2 копируется в ссылку ref1. В результате обе ссылки содержат адрес объекта, на который указывает ссылка ref2. Сам объект не копируется. Таким образом, обе ссылки указывают на один и тот же объект. При разработке программ эту особенность нужно учитывать.

Пример. В примере демонстрируется применение операции присваивания для переменных типа-значения и переменных ссылочного типа. Пример реализован для приложения типа Console Application.

using System;

namespace ConsoleApp2
{
  // Класс Integer - ссылочный тип
  class Integer
  {
    public int value; // целочисленное значение
  }

  class Program
  {
    static void Main(string[] args)
    {
      // Операция присваивания для типов-значений
      int a, b;
      a = 8;

      // значение переменной a копируется в переменную b
      b = a; // b = 8, a = 8
      Console.WriteLine("a = {0}, b = {1}", a, b);

      a = 6; // a = 6, b = 8 - переменные размещены в разных участках памяти
      Console.WriteLine("a = {0}, b = {1}", a, b);

      // Операция присваивания для ссылочных типов
      // Объявить две ссылочные переменные типа Integer
      Integer d1, d2;

      // выделить память для ссылки d1
      d1 = new Integer();
      d1.value = 37; // заполнить значением

      // выделить память для ссылки d2
      d2 = new Integer();
      d2.value = 50; // заполнить значением

      // операция присваивания ссылок - копируются только ссылки
      d2 = d1; // d2.value = 37
      Console.WriteLine("d1.value = {0}, d2.value = {1}", d1.value, d2.value);

      d2.value = 100; // d1.value = 100 - ссылки указывают на один объект (участок памяти)
      Console.WriteLine("d1.value = {0}, d2.value = {1}", d1.value, d2.value);
    }
  }
}

Результат работы программы

a = 8, b = 8
a = 6, b = 8
d1.value = 37, d2.value = 37
d1.value = 100, d2.value = 100

Как видно из результата, при присваивании ссылок

d2 = d1;

обе ссылки указывают на память, выделенную для объекта d1. Изменение значения в ссылке d2

d2.value = 100;

приводит к изменению значения в ссылке d1: d1.value = 100.

 


Связанные темы