Опубликован: 23.07.2006 | Доступ: свободный | Студентов: 2215 / 889 | Оценка: 4.28 / 4.17 | Длительность: 21:37:00
Специальности: Системный архитектор
Лекция 2:

Обзор языка C#

< Лекция 1 || Лекция 2: 123456 || Лекция 3 >

Управляющие конструкции C#

Большинство современных языков программирования содержит приблизительно одинаковый набор конструкций управления и C# не предлагает в этой области ничего радикально нового.

В С# используются обычные присваивания для простых переменных; структурные или массовые присваивания не поддерживаются.

Операторы ветвления тоже достаточно традиционны ( if , switch ), но обладают двумя особенностями. Во-первых, условие в операторе if должно вырабатывать именно булевское значение (т.е. целого значения, вырабатываемого при присваивании недостаточно), а во-вторых, каждая ветка case внутри оператора switch должна содержать явное указание о дальнейшем потоке управления (т.е. либо break , либо goto на какую-то переменную, например, на метку другой ветки).

Что касается циклов, то С# поддерживает вполне традиционные циклы, такие как do - while , while - do и циклы с итерацией for , но помимо этого, поддерживает перебор массивов и коллекций с помощью оператора foreach , как в следующем примере:

Hashtable ziphash = new Hashtable();
...
foreach (string zip in ziphash.Keys) 
{
   Console.WriteLine(zip + "          " + ziphash[zip]);
}

В этом примере надо обратить внимание на то, что перебираемый класс должен поддерживать интерфейс IEnumerator, а также на тот факт, что каждый извлекаемый из коллекции объект явным образом приводится к заявленному типу перебора (в нашем примере это string ).

Наконец, C# поддерживает структурную обработку исключений с помощью конструкций try , catch и finally . Исключения можно генерировать и явным образом с помощью конструкции throw .

Типы данных

Система типов C# полностью отражает систему типов .NET и в целом достаточно типична для современных языков. Важная особенность этой системы типов заключается в явном разделении всех типов на типы-значения и ссылочные типы (мы уже обсуждали эти пониятия в "лекции 1" ).

К типам-значениям относится широкий набор примитивных типов данных, включая целые числа различной разрядности, типы с плавающей запятой различной точности, специальный тип decimal с фиксированной точностью, предназначенный для финансовых вычислений, а также символьный тип char , способный хранить символы в формате Unicode и потому удобный при разработке интернациональных приложений. Все целочисленные типы существуют в двух вариантах: знаковом и беззнаковом. Важной особенностью переменных с плавающей запятой является то, что операции над ними никогда не производят исключений, но зато результатом работы с ними могут быть значения \pm \infty (как результат деления на ноль) или нечисловым значением, NaN (Not-A-Number, как результат деления 0 на 0 или операций, в котором один из операндов уже равняется NaN ).

Отметим, что C# содержит также специальный тип для булевских значений; переменные булевского типа могут содержать значения true или false , но в отличие от большинства современных языков программирования этим значениям не соответствует никаких численных эквивалентов (в отличие, скажем, от VB, где False соответствует 0, а True почему-то соответствует значение -1).

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

Ссылочные типы

Все ссылочные типы произведены от базового типа object, являющегося точным эквивалентом класса System.Object . Сам по себе тип object в основном используется для упаковки значений, подробно обсуждавшейся выше. Другая, более важная роль типа object заключается в том, что он является корнем для всей иерархии объектов в .NET и по умолчанию все классы унаследованы именно от System.Object . Классы могут иметь свои поля, методы, реализовывать интерфейсы и т.п. Так как классы представляют собой основной механизм организации программ и данных в C#, мы уделим им особое внимание в последующих слайдах.

Интерфейс представляет собой ссылочный тип, который может иметь только абстрактные элементы (аналогично методам, равным нулю, в С++). В частности, с помощью интерфейсов можно реализовать механизм множественного наследования - для этого необходимо унаследовать класс от нескольких элементов и затем явным образом реализовать заявленную функциональность.

Представители (delegates) являются относительно безопасной версией указателей на функции: окружение .NET гарантирует, что представители указывают именно на допустимый объект, а не просто на некоторый адрес в памяти. Основные области применения представителей - это методы обратного вызова и асинхронные обработчики событий.

Строки в C# являются полноценным ссылочным типом, но при этом обладают семантикой сравнений, характерной для типов-значений (т.е. строки равны, если равны их значения). Это можно проиллюстрировать следующим примером:

string str1 = "Hello World"; string str2 = "Hello " + "World";
if (str1 == str2)
   System.Console.WriteLine ("Strings are equal"); // will be executed

Массивы в С# бывают двух типов: многомерные (например, int [,,] определяет трехмерный массив) и невыровненные (они же массивы массивов, используемые в С++; например, int [ ] [ ] определяет двухмерный массив). Несмотря на простой внешний вид, массивы являются полноценными объектами, представляющими класс System.Array .

< Лекция 1 || Лекция 2: 123456 || Лекция 3 >