Обобщённые коллекции
Гарантируют повышенную безопасность типа. Содержатся в
System.Collections.Generic. Наиболее используемые:
· List<T>(список элементов типа Т с динамически меняющимся размером)
· Dictionary<K,V>(обобщённая коллекция пар имя/значение)
· Queue<T>(обобщённая очередь элементов типа Т)
· SortedDictionary <K,V>(обобщённая реализация сортированного
множества пар имя/значение)
· Stack<T>(обобщённый стек элементов типа Т)
· LinkedList<T>(обобщённая реализация двузначного списка)
БИЛЕТ 12
Делегаты – безопасный в отношении типов объект, указывающий на другой
метод (или список методов) приложения, который может быть вызван позднее.
Объект делегата содержит:
· Адрес метода, на котором он вызывается
· Аргументы (если есть) этого метода
· Возвращаемое значение (если есть) этого метода
Делегат указывает вызов метода в коде, но вызываемый метод определяется во
время работы программы, а не во время компиллироования. Вызываемый метод
может быть методом экземпляра, ассоциированным с объектом или статическим
методом, ассоциированным с классом.
Для определения делегата используется ключевое слово delegate. Имя делегата
может быть любым, однако сигнатура должна соответствовать сиггнатуре метода,
вызываемого делегатом. Пример: делегат, вызывающий любой метод метод,
принимающий в качестве входных данных два целых числа и возвращающий
целое число(сложение, умножение…)
public delegate int BinaryOp (int x, int y);
//класс, содержащий методы для делегата
public class SimpleMath
{
public int Add(int x, int y)
{return x+y;}
public int Sub(int x, int y)
{return x-y}
public static int Square(int x, int y)
{return a*a;}
}
class Program
{
static void Main(string[]args)
{
SimpleMath m = new SimpleMath();
BinaryOp b = new BinaryOp(m.add);
Console.WriteLine(b(10,10));
}
}
Многоадресность делегатов – способность делегата хранить несколько ссылок
на различные методы, что позволяет при вызове делегата инициировать эту
цепочку методов. Для создания цепочки методов необходимо создать экземпляр
делегата и, пользуясь операторами + или +=, добавлять методы к цепочке.
Для удаления метода из цепочки используем – или – =.
public delegate int BinaryOp (int x, int y);
public class SimpleMath
{
public int Add(int x, int y)
{return x+y;}
public int Sub(int x, int y)
{return x-y}
public static int Square(int x, int y)
{return a*a;}
}
static void Main()
{
BinaryOp a, b, c, d;
a = Add;
b = Sub;
c = a+b;
d = c–a;
}
БИЛЕТ 13
События
События позволяют упростить работу с делегатами.
События определяются ключевым словом event, именем
делегата и собственным именем:
public class SenderOfEvents
{
public delegate retval AssociatedDelegate(args);
public event AssociatedDelegate NameOfEvent;
...
}
Пример программы, реализующей событие:
{
public delegate void MyEventHandler();//Делегат,
связанный с событием
class TestEvent
{
public event MyEventHandler Triggerlt;//Событие с
// использование делегата MyEventHandler
public void Trigger()//Метод, инициирующий событие
{
Triggerlt();
}
public void MyMethod1()
{
Sistem.Console.WriteLine("Hello!");
}
public void MyMethod2()
{
Sistem.Console.WriteLine("Hello again!");
}
public void MyMethod3()
{
Sistem.Console.WriteLine("Good-bye!");
}
static void Main()
{
TestEvent myEvent = new TestEvent();
myEvent.Triggerlt += newMyEventHandler(myEvent.MyMethod1);
myEvent.Triggerlt += newMyEventHandler(myEvent.MyMethod2);
myEvent.Triggerlt += newMyEventHandler(myEvent.MyMethod3);
//Подписались на 3 метода
myEvent.Trigger();//Инициировали событие
myEvent.Triggerlt -= newMyEventHandler(myEvent.MyMethod2);
myEvent.Trigger();
}
}
}
Стандартный делегат для обработки событий
Для обработки большинства событий, возникающих при создании
интерфейса, используется стандартный делегат, возвращающий void
и имеющий два параметра типа object и eventArgs:
{
public delegate void EventHandler(object sender, EventArgs e);
...
class Car
{
public event EventHandler CarEvent;
void SomeMethod
{
if (CarEvent!=null)
{
CarEvent(this, New EventArgs());
}
}
public static void ForCarMet(object sender, EventArgs e)
{
Car c = (car).sender;
if(c.CarSpeed > 60)
{
Console.Write("Ух!!!");
}
}
}
public class EventArgs
{
public static readonly
Sistem.EventArgs Empty();
public EventArgs()
{}
}
}
Если необходимо передовать какую-то особенную информацию при генерации
события, то создаётся класс-наследник класса EventArgs.
В этом классе описываются поля, представляющие эту особенную информацию
и в дальнейшем для описания событий используется обобщённый делегат
EventHandler<T>(object sendler, T e):
{
class Car
{
public event EventHandler<CarEvents> CarExploded;
public event EventHandler<CarEvents> CarAboutToFollow;
...
void SpeedUp(int delta)
{
if(CarIsDead && CarExploded!=null)
{
CarExploded(this, new CarEvents("машины нет..."));
}
}
}
}
БИЛЕТ 14
Перегрузка операторов
C# позволяет производить перегрузку(переопределение) операторов:
· Унарные: +, -,!, ~, ++, --, true, false
· Бинарные: +, -, *, /, %, &, |, ^, <<, >>, = =,!=, >, >, >=, <=
Пример перегрузки оператора +
public static ComplexNumber operator + (ComplexNumber a, ComplexNumber b)
{
return new ComplexNumber(a+b-3);
}
Преобразование типов
· Числовые преобразования (sbyte, int, float...)
Явное преобразование требуется при попытке сохранить
большее значение в меньшем контейнере
(что может привести к потере данных)
Неявное преобразование происходит автоматически,
при помещении меньшего типа в больший
Static void Main()
{
int a = 123;
long b = a; //неявное
int c = (int)b; //явное
}
· Преобразования между связанными типами классов
Класс-наследник всегда может быть неявно приведён к
базовому классу.
Если требуется явное приведение:
{
class Base { }
class Derived: Base { }
class Program
{
static void Main(string[] args)
{
Base a;
a = new Derived(); //неявное
Derived b = (Derived)a; // для хранения базовой ссылки в
// ссылке на наследника нужно явное преобразование
}
}
}
· Преобразование между неимеющих общего предка классов
Пример: преобразование структуры Rectangle в Square:
Rectangle rect;
rect.Width = 3;
rect.Height = 10;
Square sq = (Square)rect;
БИЛЕТ 15
Обобщения (generic) – средство для получения более гибкого способа
управления данными в приложениях.
Основные проблемы необобщённых коллекций
(ArrayList, Hashtable, Queue, SortedList, Stack):
1. низкопроизводительный код
2. низкий уровень безопасности в отношении типов
3. …
Учитывая данные и другие проблемы, разработчики добавили
новое пространство имён Sistem. Collectiions. Generic. А в нём,
в свою очередь, новый набор классов коллекций – обобщённых коллекций
(List<>, Dictionary<K,V>, Queue<T>, SortedDictionary<K,V>,
Stack<T>, LinkedList<T>...)
List<> - список элементов типа Т с динамически изменяемым размером
Dictionary<K,V> - обобщённая коллекция пар имя/значение
Queue<T> - обобщённая очередь элементов типа Т
SortedDictionary<K,V> - обобщённая реализация сортированного
множества пар имя/значение
Stack<T> - обобщённый стек элементов типа Т
LinkedList<T> - обобщённая реализация двусвязного списка
Методы и применение обобщённых коллекций рассмотрим на примере:
Static void Main(string[] args)
{
//Создаём список, содержащий целочисленные значения
List<int> myInts = new List<int>();
//помещаем в список элементы
myInts.Add(5);
int x = 10;
myInts.Add(x);
//Создаём список, содержащий объекты Employee
List<Employee> otdel =new List<Employee>();
otdel.Add(new Manager());
otdel.Add(new SalesPerson());
Console.WriteLine(“в отделе работает {0} людей”, otdel.count);
}
БИЛЕТ 17
.Net сборки – имеющий версию, самоописываемый двоичный файл,
обслуживаемый Common Language Run-time (CLR).
Можно считать, что сборка – это библиотека. Сборки определяют
границы типов. Полностью клалифицированно е имятипа
получается из добавления к имени типа имени его пространства имён.
1. сборка, в которой находится его тип, определяет его сущность
2. сборки поодерживают версию:
<старший номер>.<младший номер>.<номер сборки>.<номер редакции>
3. сборки содержат информацию о каждой из сборок, к которым нужен
доступ, содержат метаданные, внутри которых вписана структура каждого
класса, интерфейса, метода…, содержащегося внутри данной сборки
4. сборки поддаются конфигурированию
Частные сборки
Частные сборки предназначены для использовании в одном приложении.
Когда среда CLR ищет частную сборку, она использует частное имя сборки
(хранится в метаданных), причём поиск осуществляется в корневом каталоге
и дочерних подкаталогах.
Общие сборки (сборки со строгим именем)
Строгое имя сбоки состоит из частного имени, версии, открытого, закрытого
ключей и обеспечивает более высокий уровень безопасности сборки и позволяет
использовать одну сборку в нескольких приложениях. Строгое имя уникально,
оно не позволяет заменить одну сборку другой, что крайне важно, в частности,
для коммерческих организаций. Сборка со строгим именем может храниться как
любой папке ПК, так и за пределами его(в сети), но чаще всего общие сборки
хранятся в GAC(Global Assembly Cache) – централизованном хранилище сборок.
В результате – экономия размера приложения. Хранящиеся в GAC сборки
публичны, если нам нужно избежать этого – помещаем сборку в корневую
папку приложения. Общие сборки могут ссылаться только на общие сборки.
Для настройки общей сборки необходимо вставить в проэкт конфигурационный
файл с именем подкаталога, в котором хранится сборка, на месте X:
<configuration>
<runtime>
<assemblyBinding xmlns=”urn:schemas-
microsoft-com:asm.vl”>
<probing privatePath=”X”/>
</assemblyBinding>
</runtime>
</configuration>