Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > .NET для новичков > Зачем нужен event?


Автор: alex_nevolin 13.2.2008, 15:43
Читаю про делегаты и эвенты.
Так и не понял назначение ключевого слова event.
Чем отличаются классы:
Код

using System;
namespace DelegatesAndEvents.Traning
{
    public delegate void MyDelegate();
    
    class Test1
    {
        private int x;
        public MyDelegate GetX;
        public MyDelegate SetX;
        public int X
        {
            get
            {
                GetX();
                return x;
            }
            set
            {
                SetX();
                x = value;
            }
        }
    }
    class Test2
    {
        private int x;
        public event MyDelegate GetX;
        public event MyDelegate SetX;
        public int X
        {
            get
            {
                GetX();
                return x;
            }
            set
            {
                SetX();
                x = value;
            }
        }
    }
    class App
    {
        static public void Main()
        {
            Test1 test1 = new Test1();
            test1.GetX += delegate() { Console.WriteLine("test1 get delegate1"); };
            test1.GetX += delegate() { Console.WriteLine("test1 get delegate2"); };
            test1.SetX += delegate() { Console.WriteLine("test1 set delegate3"); };
            test1.SetX += delegate() { Console.WriteLine("test1 set delegate4"); };
            Console.WriteLine(test1.X);
            test1.X = 5;
            Console.WriteLine(test1.X);

            Test2 test2 = new Test2();
            test2.GetX += delegate() { Console.WriteLine("test2 get delegate5"); };
            test2.GetX += delegate() { Console.WriteLine("test2 get delegate6"); };
            test2.SetX += delegate() { Console.WriteLine("test2 set delegate7"); };
            test2.SetX += delegate() { Console.WriteLine("test2 set delegate8"); };
            Console.WriteLine(test2.X);
            test2.X = 5;
            Console.WriteLine(test2.X);
        }
    }
}

Если ничем то зачем event?

Автор: QryStaL 13.2.2008, 16:16
В первом случае у тебя публичные поля GetX и SetX - нарушение инкапсуляции, данные не защищены. Более подробно почитай тут
http://www.rsdn.ru/article/dotnet/delegat.xml

Кроме того, при вызове делегат нужно проверять на null

Код

if (GetX != null)
{
    GetX();
}


Иначе, в случае, когда он не содержит ни одной ссылки на метод, вывалится исключение.

Автор: alex_nevolin 13.2.2008, 16:39
Да спасибо прочитал.
Но ответа на получил:
Цитата

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

Цитата

Но как оказалось, события .NET полностью закрыты для программиста. Они скрывают всю грязную работу за кулисами и контролировать обращение к событиям не представляется возможным. Но это утверждение верно только при стандартном способе использования событий. Также существует дополнительный расширенный режим их использования, при котором программист может самостоятельно объявить функции, управляющие подключением и отключением делегатов-обработчиков. Для этого в языке C# предусмотрена специальная конструкция, с использованием двух дополнительных ключевых слов add и remove.

Код

event DelegateName SomeEvent
{
  add
  {
    // Код, реализующий добавление делегата к списку
    // вызова события.
  }
  remove
  {
    // Код, реализующий изъятие делегата из списка вызова
    // события.
  }
}

1)Я так понимаю это аналог свойства. Т.е. приходим к схеме с  приватным делегатом и двумя методами.
2)При использовании события его так-же приходиться проверять на null.
Или я чего-то не понимаю. Но использование event не дает никаких преимуществ.

Автор: WarHog 13.2.2008, 17:11
в принципе, то, что написано в предыдущем посте (схема с  приватным статическим классом и двумя методами) внутренне реализуется на IL при объявлении события.

Автор: tol05 13.2.2008, 17:57
Цитата

Зачем нужен event?

могу доказать, что он не нужен  smile  (но только если будем спорить на деньги  smile  smile )


Цитата(QryStaL @  13.2.2008,  15:16 Найти цитируемый пост)
Кроме того, при вызове делегат нужно проверять на null

событие тоже. Вот неработающий пример
Код

public class A
    {
        public event EventHandler MyEvent;

        public void GoGo()
        {
            MyEvent(this, null);
        }
    }
...
A a = new A();
a.GoGo();


Цитата(WarHog @  13.2.2008,  16:11 Найти цитируемый пост)
alex_nevolin, методы add и remove ( точнее, add_Event() и remove_Event() ) - скрытые методы любого события, их объявлять не нужно и вызывать явно запрещено (это делают перегруженные методы += и -= соответственно) 

во-первых, для делегатов перегруженные операторы += и -= работают так же
пример
Код

a.MyDel += F;
a.MyEvent += F;

public class A
    {
        public event EventHandler MyEvent;

        public delegate void MyDelegate(object o, EventArgs a);
        public MyDelegate MyDel;
        
...

а во-вторых .... хоть методы add и remove объявлять не нужно, но вызывать их допускается внутри класса. Вот таким макаром
Код

public class A
    {
        private EventHandler MyDel;
        
        public event EventHandler MyEvent
        {
            add
            {
                MyDel += value;
                MyDel -= value;
            }
            remove
            {
                MyDel -= value;
                MyDel += value;
            }
        }

        public void GoGo()
        {
            MyDel(this, null); //будет ошибка - MyDel ВСЕГДА равен null
        }
    }

...
A a = new A();
a.MyEvent += F;
a.GoGo();

правда в этом случае event перестает быть "Field-like" (похожим на поле класса и MyEvent(...) уже не вызовешь).

"Но использование event не дает никаких преимуществ." - все правильно, мысль верная.  Только с тем условием, что ты сам все правильно напишешь, да и сумеешь обеспечить потокозащещенность методов Add и Remove (ну или Delegate.Combine и ...).
К тому же учти, если у тебя 30-50 событий... код твой распухнет. И голова - тоже smile

одним словом, event-ы - это удобная оболочка для делегатов. Обеспечивающая также потокозащищенность операций.
советую почитать Рихтера и спецификацию ЕСМА-334 (гугл в помощь) smile

Автор: alex_nevolin 13.2.2008, 18:19
Спасибо за ссылки:
Цитата

почитать Рихтера и спецификацию ЕСМА-334

Т.е. event 
Цитата
обеспечивает потокозащещенность методов Add и Remove
 генерирует их нужным образом.
Разумный довод. Спасибо всем за консультацию.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)