В этом уроке мы поговорим про типы данных в C# и .NET и про объявление и инициализацию переменных.
Типы в C# и .NET
Под типом в C# понимается: класс, интерфейс, структура, перечисление и делегат.
При этом тип может быть встроенным или пользовательским. Встроенные типы – это те, что предлагает сама платформа .NET , они входят в состав BCL. К пользовательским относятся все типы, спроектированные пользователями (или кодогенераторами).
Среди всех типов, предоставляемых BCL, в C# выделяется специальная группа, которая называется примитивные типы (иногда их называют простые). Это такие типы, для которых в языке предусмотрены специальные синтаксические конструкции для объявления и инициализации. В эту группу входят типы, которые разработчики используют чаще всего: числа, символы, строки и т.п.
Важными являются понятия ссылочных типов и типов-значений. Понимание разницы между ними является одним из фундаментальных знаний, которым должен обладать разработчик на C#.
К типам-значениям относятся числа, символы (char
), тип для представления логических значений (bool
), структуры и перечисления. К ссылочным типам относятся строки, классы, интерфейсы. В этом случае мы перечислили не все виды ссылочных типов и типов-значений, более подробно о них вы познакомитесь в следующих уроках.
Отметим, что система типов в C# поддерживает наследование. Это одни из базовых принципов объектно-ориентированного программирования. Суть в том, что вы можете создавать одни типы, которые являются наследниками других. В этом случае наследник получает в распоряжение весь функционал родительского класса, он может переопределять некоторые из методов базового класса и представляться родительским, когда это необходимо.
Родительский тип и тип-наследник связаны отношением “является”. Например, на рисунке ниже представлен вариант наследования класса Квадрат
от класса Фигура
. Можем ли мы сказать, что квадрат является фигурой? Ответ очевиден: да, можем. Поэтому логично Квадрат
сделать наследником Фигуры
.
Помимо отношения “является”, есть отношение “имеет”. Например, класс Стол
, не может быть наследником класса Ножка
, так как стол не является ножкой (и наоборот), стол состоит из столешницы и ножек. Такой тип отношения называется композицией, когда один класс включает в себя объекты других классов как структурные элементы. Со столом все более-менее ясно, но бывают ситуации, когда не так просто понять, что лучше: наследование или композиция, в этом случае можно воспользоваться вопросами “является?” и “имеет/состоит из?”. Если ответ на вопрос “является?” утвердительный, то, вероятно, мы имеем дело с наследованием. Если же мы утвердительно ответим на вопрос “имеет/состоит из?”, то с композицией. В большинстве случаев рекомендуют отдавать предпочтение композиции.
Абсолютно все классы в C# являются наследниками класса System.Object
, либо напрямую, либо косвенно (через иерархию наследования). Таким образом, объекты всех классов имеют, помимо своего специфического функционала, ещё и тот, что предоставляет System.Object
.
Тип может содержать довольно большое количество различных структурных элементов, таких как константы, поля, конструкторы экземпляров и типа, методы, перегруженные операторы, свойства и др. О них мы подробно поговорим при более глубоком обсуждении внутренней структуры типов.
Объявление и инициализация переменных
В общем случае, при объявлении переменной в C#, сначала указывается тип переменной, затем ее имя.
// Переменная типа int с именем num int num; // Переменная типа string с именем str string str;
Задание значения переменной можно произвести в момент ее объявления:
int radius = 10; string name = "John";
либо после:
string name; name = "John";
Задание значения переменной называют инициализацией.
На предыдущем шаге мы с вами говорили, что в C# есть переменные ссылочного типа и типа-значения. Более подробно о них мы поговорим далее, но что касается вопроса объявления и инициализации необходимо иметь в виду, что переменную ссылочного типа нельзя использовать до тех пор, пока она не будет проинициализирована. Дело в том, что переменные значимых типов, если им не присвоить значение, получают некоторое “значение по умолчанию”, для чисел – это ноль, для bool
– это false
. Переменные ссылочного типа по умолчанию имеют значение null
. То есть они не ссылаются ни на какой объект в памяти, и при попытке использовать такую переменную, например, получить значение свойства или вызвать метод, выполнение программы прервется с ошибкой.
Компиляция программы, представленной ниже, завершится с ошибкой, т.к. переменная str
не была проинициализирована.
string str; Console.Write(str); // Ошибка!
Примеры, которые мы с вами рассмотрели, приведены с участием переменных примитивных типов, для них используется сокращенный вариант инициализации. Для всех остальных типов инициализация производится с помощью оператора new
. Сокращенный вариант инициализации для примитивных типов во время компиляции разворачивается в полный с использованием new
. Об этом операторе мы поговорим чуть позже в этом уроке.
Если Вы хотите больше узнать про язык C#, приглашаем Вас на наш курс “C#. Базовый уровень“.