Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
OSISP Part 3.DOC
Скачиваний:
42
Добавлен:
11.05.2015
Размер:
360.45 Кб
Скачать
  1. Динамические массивы в среде. Net и языке c#.

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

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

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

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

public void TestDynAr()

{

//объявление динамического массива A1

Console.WriteLine("Введите число элементов массива A1");

int size = int.Parse(Console.ReadLine());

int[] A1 = new int[size];

Arrs.CreateOneDimAr(A1);

Arrs.PrintAr1("A1",A1);

}//TestDynAr

Для поддержки работы с массивами создан специальный класс Arrs, статические методы которого выполняют различные операции над массивами.

  1. Делегаты в среде .NET и механизм их работы.

// Определяем тип-делегат; экземпляры ссылаются на метод. // который принимает параметр типа Int32 и возвращает void internal delegate void Feedback(Int32 value);

В этом примере делегат задаст сигна­туру метода обратного вызова. Здесь Feedback определяет метод, принимающий один параметр типа Int32 и возвращающий void.

Класс Delegate является базовым для типов делегатов. Однако только система и компиляторы могут явно наследовать классы Delegate и MulticastDelegate. Также недопустимо создавать новые типы, производные от типа делегата. Класс Delegate не рассматривается как тип делегата, а является классом, наследуемым создаваемыми типами делегатов.

В большинстве языков программирования имеется ключевое слово delegate, и компиляторы этих языков способны создавать классы, производные от класса MulticastDelegate; поэтому пользователи должны использовать ключевое слово delegate, предоставляемое языком программирования.

Кроме наследуемых методов, среда CLR предоставляет два специальных метода для типов делегатов: BeginInvoke и EndInvoke.

Объявление типа делегата устанавливает контракт, определяющий сигнатуру одного или более методов. Делегат — это экземпляр типа делегата, содержащий указатели на:

метод экземпляра типа и целевой объект, который можно присваивать переменной этого типа;

метод экземпляра типа со скрытым параметром this, доступным в списке формальных параметров. Такой делегат называется открытым делегатом экземпляра;

статический метод;

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

Когда делегат представляет метод экземпляра, закрытый в отношении своего первого аргумента (наиболее типичный случай), этот делегат хранит ссылку на точку входа метода и ссылку на объект, называемый целевым, тип которого может присваиваться типу, определяемому методом. Когда delegate представляет открытый метод экземпляра, он содержит ссылку на точку входа этого метода. Сигнатура делегата должна содержать в списке формальных параметров скрытый параметр this; в таком случае делегат не содержит ссылку на целевой объект, и этот объект должен быть предоставлен при вызове делегата.

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

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

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

Комбинирующие операции, такие как Combine и Remove, не изменяют существующие делегаты. Вместо этого такие операции возвращают новый делегат, содержащий результаты операции, неизмененный делегат или null. Комбинирующие операции возвращают null, когда результатом их выполнения является делегат, не ссылающийся хотя бы на один метод. Комбинирующие операции возвращают делегат без изменений, когда запрошенная операция не произвела никакого эффекта.

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

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

Все методы в среде .NET можно разделить на две группы: статические (static) и экземплярные (instance).

Если делегат ссылается на статический метод, то все действительно просто. Так как в этом случае есть вся необходимая для вызова метода информация: адрес метода и параметры. Если же делегат ссылается на экземплярный метод, то задача усложняется. Чтобы вызвать экземплярный метод, делегату необходимо знать ссылку на объект, к которому привязан данный конкретный метод. Оказывается, что эта ссылка хранится в самом объекте делегата и указывается при его создании. На протяжении всей жизни объекта делегата данная ссылка не изменяет своего значения, она всегда постоянна и может быть задана только при его создании. Таким образом, вне зависимости от того, ссылается ли делегат на статическую функцию или на экземплярный метод, обращение к нему извне ничем отличаться не будет. Всю необходимую функциональность обеспечивает сам делегат, вкупе со средой исполнения. Это очень удобно, поскольку множество разных делегатов можно привязывать к одному событию.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]