double arrow

Типы, переменные и значения


C# является строго типизированным языком. Это означает, что все переменные, значения и промежуточные результаты вычислений всегда имеют определенный тип. При этом совместимость типов строго контролируется при трансляции программы с языка C# в CIL.

Несмотря на широкое распространение языков без типизации (например, PHP, JavaScript), строгую типизацию следует считать достоинством C#, которое позволяет защитить программу от трех видов ошибок.

1. Некорректное присваивание. Если переменная будет объявлена как имеющая числовой тип, то попытка присвоить ей символьное или какое-либо другое значение приведёт к ошибке компиляции и не даст такой программе запуститься.

2. Некорректная операция. Позволяет избежать попыток применения выражений вида «Hello world» + 1.

3. Некорректная передача параметров. Если функция «синус» ожидает, что ей будет передан числовой аргумент, то передача ей в качестве параметра строки «Hello world» может иметь непредсказуемые последствия. При помощи контроля типов такие ошибки также отсекаются на этапе компиляции.

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




// Только объявление переменной

float height;

string name;

MyClass SimpleClass;

 

// Объявление с инициализацией

char symbol = 'D';

int a = 10;

int b = a + 20;

bool c = a > b; // получит значение false - ложь.

Если по ходу программы после объявления переменной без ее инициализации программист попытается обратиться к ее значению, он получит сообщение об ошибке на этапе компиляции.

После объявления переменной она не может быть повторно объявлена с новым типом и ей нельзя присвоить значение, несовместимое с ее объявленным типом. Например, нельзя объявить int и затем присвоить ему логическое значение true. Однако значения могут быть преобразованы в другие типы, например, при их присвоении новым переменным или при передаче в качестве аргументов метода. Преобразование типов, которое не приводит к потере данных, автоматически выполняется компилятором. Для преобразования, которое может привести к потере данных, необходимо приведение в исходном коде. C# предоставляет стандартный набор встроенных числовых типов для представления целых чисел, значений с плавающей запятой, логических выражений, текстовых символов, десятичных значений и других типов данных. Существуют также встроенные типы string и object. Они доступны для использования в любой программе C#.

Примитивные типы. .NET поддерживает достаточно большой набор встроенных типов. Только C# поддерживает полный набор примитивных типов .NET. В таблице 3.1 приведены некоторые встроенные типы данных и объяснено их назначение.



Таблица 3.1. Соответствие типов C# и .NET

Имя типа в C# Имя типа в .NET Наименование типа
Sbyte System.SByte Знаковое 8-битное значение
Byte System.Byte Беззнаковое 8-битное значение
Short System.Int16 Знаковое 16-битное значение
Ushort System.UInt16 Беззнаковое 16-битное значение
Int System.Int32 Знаковое 32-битное значение
Uint System.UInt32 Беззнаковое 32-битное значение
Long System.Int64 Знаковое 64-битное значение
Ulong System.UInt64 Беззнаковое 64-битное значение
Char System.Char 16-битовый символ в формате Unicode
Float System.Single 32-битовое число с плавающей точкой
Double System.Double 64-битовое число с плавающей точкой
Boolean System.Boolean Логический тип (True/False)
Decimal System.Decimal 96-битовое знаковое число с плавающей точкой без мантисы (для экономических вычислений)

 

Типы-значения. Типы-значения не сводятся к примитивным типам и могут состоять из нескольких переменных. В C# для объявления value type используется ключевое слово struct, как в следующем примере:

struct RectVal { public int x, y, cx, cy; }

Важно понять, что тип-значение содержит само значение переменной, а не ссылку на него. Это экономит память, так как нет необходимости хранить таблицу виртуальных методов и дополнительный указатель на значение. Кроме того, использование типов-значений улучшает производительность, так как отпадает потребность в лишнем разыменовывании указателя и создании новой копии объекта в "куче". Но, с другой стороны, типы-значения имеют множество ограничений. Например, они не могут наследовать от других типов и от них также нельзя ничего унаследовать - они являются "запечатанными" (sealed). Поэтому можно считать, что типы-значения в целом ведут себя как встроенные типы (кстати, часто рекомендуют не делать типы-значения больше 12-16 байт).



Важно понимать, что при присваивании типов-значений происходит копирование значения, поэтому типы-значения редко используются, если их надо часто передавать в качестве параметров.

Типы-ссылки. Ссылочные типы представляют собой  указатель на ту или иную структуру, и  потому переменные ссылочных типов всегда  выделяются в "куче". При любом обращении к  значению ссылочных типов происходит  разыменовывание указателя, поэтому они  считаются несколько более медленными,  чем типы-значения. При создании ссылочные  типы инициализируются значением null.  Попытка обратиться к значению указателя,  равному null, приводит к появлению  NullPointerException (эта исключительная  ситуация не может возникнуть при  использовании типов-значений). При  присваивании ссылочных типов происходит  копирование адреса, а не значения  переменной, поэтому изменение значений одной переменной может повлиять на другие,  указывающие на тот же объект.

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

В C# ссылочные типы создаются с помощью ключевого слова class:

class RectRef {public int x, y, cx, cy; }



Операции и операнды







Сейчас читают про: