Язык позволяет конструировать пользовательские типы
· Перечислимые типы (enum) для значений из конкретного множества.
· Структуры (struct).
Эта схема типов сохранена и в языке C#. Однако здесь на верхнем уровне используется и другая классификация, носящая для C# принципиальный характер:
· Типы-значения (value), или значимые типы.
· Ссылочные (reference).
· Указатели (pointer).
· Тип void.
Эта классификация основана на том, где и как хранятся значения типов. Для ссылочного типа значение задает ссылку на область памяти в "куче", где расположен соответствующий объект. Для значимого типа используется прямая адресация, значение хранит собственно данные, и память для них отводится, как правило, в стеке. Указатели имеют ограниченную область действия и могут использоваться только в небезопасных блоках, помеченных как unsafe. Особый статус имеет и тип void, указывающий на отсутствие какого-либо значения.
к значимым типам относятся: логический, арифметический, структуры, перечисление. Массивы, строки и классы относятся к ссылочным типам. Структуры C# - частный случай класса. Определив свой класс как структуру, программист получает возможность отнести класс к значимым типам. встроенные типы C# фактически совпадают с системными типами каркаса Net Framework, размещенными в пространстве имен System.
Приведение и преобразование типов (руководство по программированию в C#)
Иногда может быть необходимым скопировать значение в переменную или параметр метода другого типа. Операции такого вида называются преобразованиями типов. В C# можно выполнять следующие виды преобразований:
· Неявные преобразования. Не требуется никакого специального синтаксиса, поскольку преобразование безопасно для типов и данные не теряются.
· Явные преобразования (приведения). Для явных преобразований необходим оператор приведения. Исходная переменная и переменная назначения совместимы, но имеется риск потери данных, поскольку тип переменной назначения имеет меньший размер, чем у исходной переменной.
· Пользовательские преобразования. Пользовательские преобразования выполняются специальными методами, которые можно определить для включения явных и неявных преобразований между пользовательскими типами, не имеющих отношения базовый класс — производный класс.
· Преобразования с помощью вспомогательных классов. Для преобразования между несовместимыми типами, например целые числа и объекты System.DateTime, класс System.BitConverter, класс System.Convert и методы Parse встроенных числовых типов.
Неявные преобразования
Для встроенных числовых типов неявное преобразование можно выполнить, сохраняемое значение может уместиться в переменной.
int num = 2147483647;
long bigNum = num;
Для ссылочных типов всегда существует неявное преобразование из класса в любой из его прямых или косвенных базовых классов или интерфейсов.
Derived d = new Derived();
Base b = d;
Явные преобразования
Приведение(Явное преобраование) является способом явно указать компилятору, что нужно сделать преобразование. Для этого заключите тип, в который производится приведение, в скобки перед преобразуемым.
double x = 1234.7;
int a;
a = (int)x;
Для ссылочных типов явное приведение необходимо, если нужно выполнить преобразование из базового типа в производный тип:
Giraffe g = new Giraffe();
Animal a = g;
Giraffe g2 = (Giraffe) a;
Классы
Класс — это конструктор, который позволяет создавать свои собственные пользовательские типы путем группирования переменных других типов, методов и событий. Он определяет данные и поведение типа. Если класс не объявлен статическим, то клиентский код может его использовать, создав объекты или экземпляры, назначенные переменной. Переменная остается в памяти, пока все ссылки на нее не выйдут из области видимости. Если класс объявляется статическим, то в памяти остается только одна копия и клиентский код может получить к ней доступ только посредством самого класса.
Члены
В следующем списке перечислены все возможные типы членов, которые можно объявлять в классе или в структуре.
· Поля
· Константы
· Свойства
· Методы
· Конструкторы
· Деструкторы
· События
· Индексаторы
· Операторы
· Вложенные типы
Поля
Переменная field имеет любой тип, непосредственно объявленный в классе или структуре. Поля являются членами содержащихся в них типов.
Класс или структура могут иметь поля экземпляра или статические поля, либо поля обоих типов. Поля экземпляра определяются экземпляром типа.
Как правило, используются поля только для переменных, имеющих доступность private или protected. Данные, которые класс представляют клиентскому коду, должны обеспечиваться методами, свойствами и индексаторами. Закрытое поле, которое хранит данные, представленные открытым свойством, называется резервным хранилищем или резервным полем.
Поля обычно хранят данные, которые должны быть доступными нескольким методам класса и должны храниться дольше, чем время существования любого отдельного метода. Переменные, не используемые вне области одного метода, должны быть объявлены как локальные переменные внутри самого тела метода.
Поля объявляются в блоке класса путем указания уровня доступа поля, за которым следует тип поля и имя поля.
Для доступа к члену объекта нужно добавить точку после имени объекта и указать имя поля: objectname.fieldname.
Полю можно назначить первоначальное значение, используя оператор присвоения при объявлении поля.
Поля инициализируются непосредственно перед вызовом конструктора для экземпляра объекта.
Поля могут быть отмечены модификаторами public, private, protected, internal или protected internal. Эти модификаторы доступа определяют порядок доступа к полю для пользователей класса.
Также при необходимости поле может быть объявлено с модификатором static.
Также при необходимости поле может быть объявлено с модификатором readonly. Полю с этим модификатором (то есть полю, доступному только для чтения) значения могут быть присвоены только при инициализации или в конструкторе.