Делегаты и события

Делегаты

О делегате можно подумать как о некоем интерфейсе с четко заданной сигнатурой. Тогда экземпляр делегата - это объект, который этот интерфейс реализует. Он хранит ссылку на метод, и, если метод экземплярный, то и ссылку на экземпляр объекта, в котором «находится» целевой метод. Суть делегата - возможность делать вызов метода с заранее определенной сигнатурой Имея экземпляр делегата, можно вызвать любой существующий метод, сигнатура которого будет идентична сигнатуре метода, определенного в "интерфейсе"(делегате). Делегат объявляется при помощи ключевого слова delegate

public delegate string SasDelegate (int x);

public class Sas
     {
         public delegate void AsaDelegate (char a, char b);
     }

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

/* По сути, мы создаем новый делегат так же, как и любой объект, но в конструктор помещаем метод. */
 SasDelegate sas1 = new SasDelegate(InstanceMethod);

 /* Все тоже самое, но целевой метод находится в другом классе(в данном случае в классе OtherInstanceClass) */
 SasDelegate sas2 = new SasDelegate(OtherInstanceClass.InstanceMethod);

 /* Целевой метод так же может быть статическим */
 SasDelegate sas = new SasDelegate(StaticMethod);

Конструктор делегата имеет 2 параметра - сслыку на метод(System.IntPtr) и ссылку на экземпляр объекта(System.Object). Если метод указанный в параметре System.IntPtr статический, параметр System.Object примет значение null.

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

Экземпляры делегатов вызываются таким же образом как и обычные методы

string data = sas(228);

События

Событие, это не что иное, как ситуация, при возникновении которой, произойдет действие или несколько действий. Говоря языком программного моделирования, Событие — это именованный делегат, при вызове которого, будут запущены все подписавшиеся на момент вызова события методы заданной сигнатуры. Хоть события и основаны на делегатах, это НЕ экземпляры делегатов.

События являются парами методов, связанные между собой так, чтобы языковая среда чётко знала, что она «имеет дело» не с «простыми» методами, а с методами, которые представляют события. Когда событие срабатывает, происходит поочерёдный (один за другим) вызов обработчиков.

Так как события и делегаты связаны, для создания события потребуется делегат.

class Sas
{
    public delegate void MethodContainer();
    // /~
}

Событие создается при помощи ключевого слова event. Событие имеет синтаксис public event <НазваниеДелегата> <НазваниеСобытия>; НазваниеДелегата — это имя делегата, на который «ссылаются» методы.

class Sas
{
    public delegate void MethodContainer();

    //Событие mEvent c типом делегата MethodContainer.
    public event MethodContainer mEvent;

    // /~
}

Следует указать событию методы, которые должны запуститься. <КлассИлиОбъект>.<ИмяСобытия> += <КлассЧейМетодДолженЗапуститься>.<МетодПодходящийПоСигнатуре>.

    //Экземпляры классов которые должны запуститься.
    Class1 class1 = new Class1();
    Class2 class2 = new Class2();
    //Они должны будут как-то среагировать на возникновение события.
    //Допустим, у них есть метод React().
    //Тогда, подписываем их на событие.
    Sas.mEvent += class1.React; // Никаких скобочек - метод не вызывается.
    Sas.mEvent += class2.React;

Необходимо создать условие, когда событие будет вызвано.

class Sas
{
    public delegate void MethodContainer();

    public event MethodContainer mEvent;

    private void someMethod()
    {
        //что-то происходит

        //проверка условия
        if (somethingIsHappen())
        {
            mEvent();//Запуск события
        }
        //Снова что-то происходит
    }
}

От события можно отписаться путем <КлассИлиОбъект>.<ИмяСобытия> -= <КлассЧейМетодДолженЗапуститься>.<МетодПодходящийПоСигнатуре>. Если на событие никто не подписан и его делегат пустой, возникнет ошибка.

results matching ""

    No results matching ""