Делегаты. Назначение, синтаксис объявления, использование делегата. Событийная модель.
Жизненный цикл объекта.
Ссылочные объекты выделяются с помощью оператора new. Они живут до тех пор, пока среди всех структур данных существует хотя бы 1 ссылка на этот объект. Если это не так, то объект попадает в сборщик мусора (GC).
Метод Object.Finalize() вызывается перед тем, как объект будет физически разрушен сборщиком мусора. Вообще говоря процесс разрушения объекта можно остановить, т.е., если даже объект попал в сборщик мусора, ссылку на объект можно реанимировать. Но применение подобной технологии очень ограничено.
GC – это фоновый поток, который следит за неиспользуемыми объектами.
В своей работе GC использует особый алгоритм, который позволяет ему оптимизировать процесс разрушения объектов. Узнать в точности, когда объект разрушен или не разрушен по сути дела невозможно, т.е. момент настоящего разрушения объекта недетерминирован. GC накапливает и разрушает объекты по поколениям.
У GC есть несколько методов, которые позволяют узнать размеры поколений объектов и форсировать сборку мусора.
Важнейшие методы: GC.Collect().
Для того, чтобы гарантировать, что некоторый ресурс освобождается в нужный момент времени, предназначен интерфейс IDisposable. У него есть только один метод void Dispose(). Его и надо написать, если класс реализует данный интерфейс.
Ресурс освобождается посредством вызова метода Dispose() в нужной программисту точке.
Реализация метода Dispose() обычно такова:
class MyClass : IDisposable
{
private bool disposed = false;
public void Dispose()
{
if(!disposed)
{
// освобождение ресурса
// подавление метода Finalize()
GC.SupressFinalize(this);
disposed = true;
}
}
}
Блок using автоматически вызывает в конце метод Dispose () всех перечисленных в объявлении объектов.
using (объявление объекта)
{
// действие
}
Объявление объекта представляет собой список объявлений и возможно создания объектов, которые реализуют IDisposable.
Обобщенные методы. Объявление и детализация методов типами пользователя.
C# поддерживает обобщенные методы. Любое объявление метода внутри структуры, класса или интерфейса может быть сделано обобщенным. Сюда входят и статические, и виртуальные или абстрактные методы. К тому же можно объявлять обобщенные методы в необобщенных типах. Чтобы объявить обобщенный метод, просто необходимо добавить аргумент типа в список аргументов в конце имени метода, но перед списком его параметров. Можно объявить любые типы в списке параметров метода, включая и тип возврата метода, как обобщенные параметры.
Синтаксис объявления обобщённого метода:
[модификатор доступа] [тип возвращаемого значения] <имя метода> <список параметров типа> (список аргументов)
Пример вызова:
public void MyMethod<T> (T myVar)
{ T second Var = myVar; }
int a = 0;
obj.MyMethod(a); obj.MyMethod<int>(a);
Атрибуты. Назначение атрибутов. Базовый класс атрибута. Аннотирование класса атрибутами.
Это специальные классы, объекты которых можно присоединить к другим классам. Посредствам такой технологии можно связывать дополнительную информацию с классами или членами классов на этапе компиляции.
Основное назначение атрибутов – создание технологических подстроек, которые в последствие можно применить к пользовательским классам без изменения или расширения собственной функциональности класса.
Атрибуты указываются перед классами или элементом класса в [].
Базовым классом всех атрибутов является класс System.Attribute. Все стандартные или пользовательские атрибуты должны наследоваться от этого класса, и имя класса должно быть: <…> Attribute
При указании атрибута можно воспользоваться любым имеющимся у него конструктором, т.е. указать передаваемые в конструктор параметры.
Атрибуты часто используются для формирования дополнительной информации о сборке или приложении AssemblyInfo.cs
Имеется огромное количество встроенных атрибутов, которые отвечают за определенные технологии.
Наиболее популярные:
1) System.Diagnostics.ConditionalAttribute;
2) System.ObsoleteAttribute;
3) System.SerializableAttribute;
4) System.Reflection.AssemblyDelaySignAttribute;
5) XML [Node, Attribute, Iquore] Attribute.
Привязка объектов атрибутов к классам происходит неявным образом, в момент загрузки сборки.
Расширяющие методы.
Достаточно часто пользователю предлагается герметизированные классы. Эти классы обладают достаточно большой функциональностью. Но пользователю нужны другие методы, которые составляются на основе базовой общедоступной функциональности. Если наследование произвести нельзя, то и эти методы добавить в классы тоже нельзя. Технически обойти такую сложность можно с помощью статических методов с передачей объекта в качестве параметра. Но синтаксически это не выглядит как программирование в ООП стиле.
Расширяющий метод – это просто особый синтаксис статического метода.
Пример расширяющего метода (может находится только в статическом классе):
public static class ExtensionMethods
{
static StreamWriter writer = new StreamWriter(“log.txt”, true);
public static void SendToLog(this string str)
{writer.WriteLine(str);}
}
string myStr = “Моя строка”;
myStr.SendToLog();
Первый параметр в сигнатуре расширяющего метода указывается с ключевым словом this. Вызов в дальнейшем расширяющего метода осуществляется на объекте совместного типа, так как-будто это метод класса. Остальные параметры записываются как обычные параметры метода. Их и только их надо будет указать при вызове расширяющего метода.
Жизненный цикл объекта.
Ссылочные объекты выделяются с помощью оператора new. Они живут до тех пор, пока среди всех структур данных существует хотя бы 1 ссылка на этот объект. Если это не так, то объект попадает в сборщик мусора (GC).
Метод Object.Finalize() вызывается перед тем, как объект будет физически разрушен сборщиком мусора. Вообще говоря процесс разрушения объекта можно остановить, т.е., если даже объект попал в сборщик мусора, ссылку на объект можно реанимировать. Но применение подобной технологии очень ограничено.
GC – это фоновый поток, который следит за неиспользуемыми объектами.
В своей работе GC использует особый алгоритм, который позволяет ему оптимизировать процесс разрушения объектов. Узнать в точности, когда объект разрушен или не разрушен по сути дела невозможно, т.е. момент настоящего разрушения объекта недетерминирован. GC накапливает и разрушает объекты по поколениям.
У GC есть несколько методов, которые позволяют узнать размеры поколений объектов и форсировать сборку мусора.
Важнейшие методы: GC.Collect().
Для того, чтобы гарантировать, что некоторый ресурс освобождается в нужный момент времени, предназначен интерфейс IDisposable. У него есть только один метод void Dispose(). Его и надо написать, если класс реализует данный интерфейс.
Ресурс освобождается посредством вызова метода Dispose() в нужной программисту точке.
Реализация метода Dispose() обычно такова:
class MyClass : IDisposable
{
private bool disposed = false;
public void Dispose()
{
if(!disposed)
{
// освобождение ресурса
// подавление метода Finalize()
GC.SupressFinalize(this);
disposed = true;
}
}
}
Блок using автоматически вызывает в конце метод Dispose () всех перечисленных в объявлении объектов.
using (объявление объекта)
{
// действие
}
Объявление объекта представляет собой список объявлений и возможно создания объектов, которые реализуют IDisposable.
Делегаты. Назначение, синтаксис объявления, использование делегата. Событийная модель.
Делегат(delegate) -это ссылочный тип, инкапсулирующий метод с указанной сигнатурой и возвращаемым типом. Каждый делегат описывает множество функций с указанной сигнатурой, каждая функция (метод), сигнатура которой совпадает с сигнатурой делегата, может рассматриваться как экземпляр класса, заданного делегатом. Синтаксис делегата:
[<спецификатор доступа>] delegate<тип результата> <имя класса> (<список аргументов>);
Спецификатор доступа может быть опущен, при этом делегат может быть объявлен: 1) непосредственно в пространстве имен, вместе с объявлениями других классов, сигнатур, интерфейсов; 2) внутри другого класса, вместе с объявлениями методов и свойств(как объявление вложенного класса); Делегаты не задают реализацию, а экземпляры делегата можно рассмотреть как ссылки (указатели на функции), при этом методы классов с соответствующей сигнатурой будут рассматриваться как объекты, которые хранятся в динамической памяти, вследствие выполнения произойдет связывание объекта со ссылкой. Применение: делегаты указывают методы, которые могут быть использованы при обработке событий, а также для реализации обратных вызовов в программе. Кроме того они применяются для указания статических методов и методов экземпляра, о которых ничего не известно до этапа выполнения. Также существует и класс Delegate,который является абстрактным классом: public abstract class Delegate: ICloneable, ISerializable. Для абстрактных классов реализация не определена, т.е. нельзя создавать экземпляры класса, но этот класс имеет свойство - их можно комбинировать. Т.е. к экземпляру делегата разрешается поочередно присоединить другие экземпляры делегата того же типа. Поскольку каждый экземпляр хранит ссылку на функцию, то в результате создается список ссылок или список вызовов(invocation list). Когда вызывается экземпляр, имеющий список вызова, то затем в порядке присоединения начинают вызываться и выполняться функции, заданные ссылками. Так один вызов порождает выполнение списка работ. На ряду с операциями присоединения делегатов существует и обратная операция удаления делегатов из списка. К основным методам и свойствам класса Delegateотносятся 2 статических метода: Combine(присоединяет экземпляры делегата к списку) и Remove(удаляет).
Combine(список атрибутов); Remove(список атрибутов); Пример: Combine(del1,del2); Remove(del1,del2); Недостаток - необходимо атрибуты явно преобразовывать к нужному типу. Чтобы этого не делать существуют операции «+» и «–», которые добавляют или удаляют делегаты из списка вызовов. Пример: del1 += del2; del1-=del2; Класс Delegateимеет 2 динамических свойства: Method и Target, которые служат для получения подробных сведений о делегате. Свойство Method возвращает объект класса MethodInfo из пространства имен Reflection. Свойство Target возвращает информацию об объекте, вызвавшем делегат, в тех случаях, когда делегат, инициируется не статическим методом класса, а динамическим, связанным с вызвавшим его объектом.