Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Зачем нужен event? Помогите понять суть 
V
    Опции темы
alex_nevolin
Дата 13.2.2008, 15:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 86
Регистрация: 13.8.2007

Репутация: нет
Всего: 4



Читаю про делегаты и эвенты.
Так и не понял назначение ключевого слова 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?
PM MAIL   Вверх
QryStaL
Дата 13.2.2008, 16:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Intellectual feast
**


Профиль
Группа: Участник
Сообщений: 914
Регистрация: 30.11.2005

Репутация: 10
Всего: 32



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

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

Код

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


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


--------------------
I don't need a reason being who I am...
PM MAIL ICQ   Вверх
alex_nevolin
Дата 13.2.2008, 16:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 86
Регистрация: 13.8.2007

Репутация: нет
Всего: 4



Да спасибо прочитал.
Но ответа на получил:
Цитата

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

Цитата

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

Код

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

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

PM MAIL   Вверх
WarHog
Дата 13.2.2008, 17:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 122
Регистрация: 20.10.2007
Где: Воронеж

Репутация: нет
Всего: 2



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

Это сообщение отредактировал(а) WarHog - 13.2.2008, 17:26
--------------------
PM MAIL   Вверх
tol05
Дата 13.2.2008, 17:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1632
Регистрация: 21.12.2006
Где: Харьков

Репутация: 36
Всего: 170



Цитата

Зачем нужен 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


--------------------
На хорошей работе и сны хорошие снятся.
PM MAIL   Вверх
alex_nevolin
Дата 13.2.2008, 18:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 86
Регистрация: 13.8.2007

Репутация: нет
Всего: 4



Спасибо за ссылки:
Цитата

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

Т.е. event 
Цитата
обеспечивает потокозащещенность методов Add и Remove
 генерирует их нужным образом.
Разумный довод. Спасибо всем за консультацию.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
Partizan
PashaPash

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, Partizan, PashaPash.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | .NET для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.1347 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.