Опубликован: 25.09.2008 | Доступ: свободный | Студентов: 3223 / 516 | Оценка: 4.32 / 3.98 | Длительность: 18:50:00
ISBN: 978-5-94774-991-5
Лекция 3:

Основы языка 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, позволяющие четко указывать на направление передачи параметров: в процедуру или из нее.

Очень важным компонентом языка является возможность использования динамических массивов и расширенные возможности при работе со строками.