Основы языка C#
Структуры
Во многих отношениях структуры можно рассматривать как особую разновидность классов.
Для структур можно определять конструкторы, реализовывать интерфейсы. Однако для структур в C# не существует базового класса, поэтому все структуры являются производными от типа ValueType.
Простейший пример структуры можно представить так:
public struct Employee
{
public string name;
public string type;
public int deptID;
}Использование структуры возможно следующим образом. Сначала ее необходимо создать. В момент создания структуры для нее выделяется память в области стека. В дальнейшем к элементам структуры возможно обращение путем указания имени структуры и имени элемента, разделенных точкой:
Employee Alex; Alex.name = "Alex"; Alex.type = "manager"; Alex.deptID = 2310;
В реальной системе для более удобного использования структур целесообразно определить конструктор или несколько конструкторов. При этом необходимо помнить, что в структурах невозможно переопределить конструктор по умолчанию (без параметров). Все определенные в структуре конструкторы должны принимать параметры. Ниже представлен пример конструктора структуры.
public Employee(int DeptID, string Name, string EmpType)
{
deptID = DeptID;
type = EmpType;
name = Name;
}Использование конструктора выглядит следующим образом:
Employee Nick=new Employee(278,"Nick","worker");
Как видно, для вызова конструктора структуры необходимо использовать ключевое слово new.
Аналогичным образом становится возможным создание и использование методов структур.
Коллекции
Массивы - это удобное средство организации хранения и упорядочивания информации. Однако при работе с массивами практически всегда возникают задачи, которые связаны с обработкой данных, содержащихся в них. В современном программировании очень часто элементами массива являются объекты, над которыми необходимо выполнять различные действия. В силу особенностей коллекций, а также учитывая тот факт, что упор при изложении данного материала был сделан на использование коллекций для хранения именно объектов, раздел, посвященный коллекциям, расположен после раздела, посвященного классам и структурам.
Ранее был рассмотрен класс Array, в котором реализован целый набор часто используемых операций над элементами массива, таких как сортировка, клонирование, перечисления и расстановка элементов в обратном порядке. Тем не менее при работе с массивами возникает и целый ряд других задач. Решением этих задач и занимаются коллекции, позволяющие организовывать элементы специальным образом и производить впоследствии над ними определенный набор операций.
Все определенные в .NET Framework коллекции расположены в пространстве имен System.Collections. Наиболее часто используемые коллекции этого пространства имен представлены ниже.
| ArrayList | Массив объектов, динамически изменяющий свой размер. |
| Hashtable | Набор взаимосвязанных ключей и значений, основанных на хэш-коде ключа. |
| Queue | Стандартная очередь, реализованная по принципу "первым вошел, первым вышел" (FIFO – First In First Out). |
| SortedList | Представляет класс, элементами которого могут быть пары "ключ-значение", отсортированные по значению ключа и предоставляющие доступ к элементам по их порядковому номеру (индексу). |
| Stack | Очередь, реализованная по принципу "последним вошел, первым вышел" (LIFO – Last In First Out). |
В пространстве имен System.Collections.Specialized расположены классы, предназначенные для использования в специальных случаях. Так, класс StringCollection представляет набор строк. Класс StringDictionary представляет собой набор строковых значений, состоящих из пар "ключ-значение", в качестве значений которых используется строка.
В данной лекции будут рассмотрены общие вопросы применения коллекций. Для более детального изучения их особенностей и возможностей рекомендуется ознакомиться с разделом "Интерфейсы", а также использовать дополнительную литературу и справочную систему MSDN.
Рассмотрим пример применения коллекций на примере класса ArrayList. Для этого воспользуемся рассмотренным ранее классом Client. Очень часто возникает ситуация, при которой необходимо бывает помещать объекты в список или массив для их дальнейшей обработки. Конечно, при этом может быть достаточно тех возможностей, которые предоставляют стандартные массивы C#, рассмотренные ранее. Однако коллекции, как уже было сказано, обладают более широкими возможностями и, следовательно, их применение предпочтительно по сравнению с массивами. Так, для обработки данных о клиентах создадим класс Clients, предназначенный для хранения списка клиентов и его обработки. При этом необходимо учесть, что класс Clients должен обеспечивать возможность добавления, удаления и нумерации элементов (клиентов). Для реализации этой функциональности необходимо использовать класс ArrayList в качестве вложенного в класс Clients. Таким образом, нам необходимо определить в данном классе элемент, позволяющий вести список клиентов, а также реализовать набор открытых методов, которые будут передавать вызовы на выполнение различных действий внутреннему классу, производному от ArrayList. Пример исходного кода класса Clients приведен ниже.
public class Clients
{
private ArrayList ClientsList;
public Clients()
{
ClientsList=new ArrayList();
}
public int ClientsCount
{
get
{
return ClientsList.Count;
}
}
public void AddClient(Client c)
{
ClientsList.Add(c);
}
public void RemoveClient(int ClientToRemove)
{
ClientsList.RemoveAt(ClientToRemove);
}
public Client GetClient(int ClientID)
{
return (Client)ClientsList[ClientID];
}
}Использование такого класса представляется очень простым:
Clients cl=new Clients();
cl.AddClient(new Client("Сидоров","9002",new
DateTime(1980,12,21)));
cl.AddClient(new Client("Петров","9004",new
DateTime(1975,03,15)));Теперь становится возможным обращение к любому классу Client, помещенному в коллекцию Clients посредством метода GetClient:
Client MyClient = cl.GetClient(1); Response.Write(MyClient.name);
Результатом работы этого фрагмента программы будет строка "Петров".
Тем не менее существует несколько неудобств от использования класса Clients в его нынешней реализации. Во-первых, более привычным обращением к элементу массива либо списка в языке C# является использование индексаторов, обозначаемых в виде квадратных скобок. Для реализации этой возможности в классе Clients необходимо создать индексатор:
public Clients this[int pos]
{
get
{
return ((Clients)ClientsList[pos]);
}
set
{
ClientsList[pos] = value;
}
}Как видно, от обычного метода индексатор отличается именем ( this ), а также наличием квадратных скобок, в которых указывается параметр - номер извлекаемого элемента. С помощью индексатора становится возможным извлечение элемента из коллекции, а также запись элемента в коллекцию под определенным номером:
Response.Write(cl[1].name); cl[1].name = "Сидоров"; Response.Write(cl[1].name);
Теперь можно организовать обработку элементов массива в цикле. При работе с коллекциями довольно удобной является возможность использования цикла foreach. Для реализации такой функциональности при работе с классом Clients необходимо использовать метод GetEnumerator() интерфейса IEnumerator - задать наследование классом Clients интерфейса IEnumerator и реализовать метод, как показано ниже.
public class Clients:IEnumerable
{
public IEnumerator GetEnumerator()
{
return ClientsList.GetEnumerator();
}
}Пример применения цикла foreach с использованием класса Clients показан ниже.
foreach (Clients c in cl)
{
Response.Write("Имя="+c.name+" ");
Response.Write("Паспорт="+c.passport+" ");
Response.Write("Возраст=" + c.age);
Response.Write("</br>");
}Краткие итоги
Язык C# является наследником C++, перенимая основные элементы синтаксиса и базовую систему типов. При этом в него были введены некоторые элементы, свойственные другим языкам программирования, таким, например, как Visual Basic. В C# существует достаточно много нововведений, направленных на упрощение работы с ним и на повышение гибкости его использования.
Важные отличия произошли в системе типов языка C#. Все типы были разделены на значимые и ссылочные. Причем в среде .NET Framework были определены правила использования тем или иным типом доступной оперативной памяти, которые должен учитывать программист в процессе разработки программы.
Важнейшей характеристикой языка является тот факт, что он является полностью объектно-ориентированным. Это означает, что абсолютно все типы данных описываются с помощью классов. Основу синтаксиса описания классов C# также позаимствовал у C++. Однако и здесь были введены новые элементы, которые способствуют решению части неудобств, возникающих при использовании C++. Правила передачи параметров в процедуры и функции также претерпели некоторые изменения. В частности, появились ключевые слова in и out, позволяющие четко указывать на направление передачи параметров: в процедуру или из нее.
Очень важным компонентом языка является возможность использования динамических массивов и расширенные возможности при работе со строками.