Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: вопрос по делегатам и ивентам  (Прочитано 8193 раз)
0 Пользователей и 1 Гость смотрят эту тему.
little
Помогающий

de
Offline Offline
Пол: Мужской

« : 07-08-2007 08:23 » 

Вопрос номер раз:
Чем отличаются привязки обработчиков: 
Код:
SomeEvent += SomeEventHandler;
и 
Код:
SomeEvent += new EventHandler(SimeEventHandler);

Вопрос номер два:
Как можно наследовать события?
т.е.
Код:
public class Base
{
  public delegate void SomeDelegate();
  public event SomeDelegate SomeEvent;
}

public class Derived : Base
{
  public void SomeMethod()
  {
    // вот эта хрень не работает:
    if (SomeEvent != null)
      SomeEvent();
  }
}

Компилятор ругается, что SomeEvent в левой части может использоваться только в операциях += и -=, за исключением самого класса Base.

Что посоветуете? как можно полноценно пользоватья событиями родительских классов?
Записан
nikedeforest
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 07-08-2007 08:40 » 

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

ещё один вопрос ...
Алексей++
кот глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #2 : 07-08-2007 08:44 » 

а если так
if (SomeEvent)
{
   SomeEvent();
}

Записан

nikedeforest
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 07-08-2007 09:11 » 

По второму. Рекомендации МАйкрософт по использованию событий такого плана:
В базовом классе создавай метод OnEvent() в твоем случае защищенныйи виртуальный и в нем напиши код
Код:
protected virtual void OnEvent()
{
if( SomeEvent!=null)
SomeEvent();
}

В классе потомке можешь переопределить данный метод,  но обязательно вызови метод базового класса.
Вот такая методика.
Записан

ещё один вопрос ...
nikedeforest
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #4 : 07-08-2007 09:14 » 

Алексей, .НЕт не позволяет такого раздолбайства с типами. Так, как предложил ты, можно поступать только с переменными типа bool. Такой практики, что если число типа int равно 0, то ложь, иначе истина в .НЕТ не существует.
Записан

ещё один вопрос ...
Алексей++
кот глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #5 : 07-08-2007 09:25 » 

nikedeforest, в нормальном человеческом с++ все указатели обычно инициализируют 0. Так что не только bool

лишний раз убеждаюсь, что по доброй воле не перейду на косноязычный нет )
« Последнее редактирование: 07-08-2007 09:27 от Алексей1153++ » Записан

nikedeforest
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #6 : 07-08-2007 09:47 » 

Вообще-то указатели вроде лучше инициализировать Null в С++ и проверять как раз конкретно на равенство Null.
Записан

ещё один вопрос ...
Алексей++
кот глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #7 : 07-08-2007 09:56 » 

nikedeforest, неважно, NULL == (void*)0 , так что один крен.
Записан

little
Помогающий

de
Offline Offline
Пол: Мужской

« Ответ #8 : 07-08-2007 09:58 » 

Пока по первому вопросу. Ничем не отличаются. В первом случае, я так понимаю, экземпляр делегата был создан заранее и только потом ты включаешь его в обработку события. Во втором случае создание делегата и подпись его на события происходит в одной строке.
Что значит - "создание делегата"? Он ведь так и так у меня уже написан и в new я ссылаюсь на уже существующий обработчик. Или new все таки создает какой-то новый экземпляр делегата для непонятно каких целей? Во всех хелпах у мелкософта импользуется конструкция с new, я же использую первый вариант и никакой разницы не наблюдаю.
Может такое быть, что и первый, и второй вариант работают абсолютно одинаково, просто в первом варианте экземпляр делегата создается неявно?
Записан
nikedeforest
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #9 : 07-08-2007 11:58 » 

little, ты сначала ведь  пишешь
public delegate void MyDlg(object obj, EventArgs arg);

Потом где-то позднеее ты пишешь
MyDlg CurrDlg=new MyDlg(<Имя метода>);  //создаешь экземпляр делегата

А потом ты подписываешься на событие
MyEvent+=CurrDlg;

Так вот весь предыдущий код (за исключеним первой строки) можно записать было так
MyEvent+=new MyDlg(<Имя метода>)
Записан

ещё один вопрос ...
little
Помогающий

de
Offline Offline
Пол: Мужской

« Ответ #10 : 07-08-2007 12:09 » 

Потом где-то позднеее ты пишешь
MyDlg CurrDlg=new MyDlg(<Имя метода>);  //создаешь экземпляр делегата
Этого я не пишу, только объявляю делегат, а потом подписываюсь. Явного создания делегата, как в твоем примере, я не вижу.

ЗЫ: речь идет про C#
Записан
nikedeforest
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #11 : 07-08-2007 12:59 » 

А как ты пишешь?
Записан

ещё один вопрос ...
little
Помогающий

de
Offline Offline
Пол: Мужской

« Ответ #12 : 08-08-2007 06:41 » 

примерно так:

Код:
public class Class1
{
  public delegate void SomeDelegate();
  public event SomeDelegate SomeEvent;
}

public class Class2
{
  private Class1 cls1 = new Class1();

  public void SomeEventHandler()
  {
    //...
  } 

  public void SomeMethod()
  {
    cls.SomeEvent += SomeEventHandler;
  }
}
т.е. явного создания экземпляра делегата я тут не наблюдаю...
Записан
nikedeforest
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #13 : 08-08-2007 07:36 » 

В принципе я объяснил бы это вот так:
Код:
using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleTemp
{
    public delegate void MyDelegate();
    class Program
    {
        static void Running()
        {
            Console.WriteLine("Runing");
        }

        static void RunDelegate(MyDelegate dlg)
        {
            dlg();
        }

        static void Main(string[] args)
        {
            MyDelegate dlg = new MyDelegate(Running);
            RunDelegate(dlg);
            RunDelegate(Running);
        }
    }
}


Вспомнив, что делегат- аналог указателя на функцию в С++ решил состряпать этот пример. Сработал. Просто вспомнил работу с указателем на функцию. В метод можно было передать как указатель на функцию, так и саму функцию напрямую.  Аналогия сработала.
Об остальном можно только предполагать, т.к. реализация делегатов от нас скрыта.
Ну естественно, что по факту передается указатель на функцию.
Ну и как ответ на твой первый вопрос - для события по барабану как ты напишешь, потому как все это тонкости работы делегата.
« Последнее редактирование: 08-08-2007 07:38 от nikedeforest » Записан

ещё один вопрос ...
little
Помогающий

de
Offline Offline
Пол: Мужской

« Ответ #14 : 08-08-2007 08:03 » 

Ну и как ответ на твой первый вопрос - для события по барабану как ты напишешь, потому как все это тонкости работы делегата.
Что и требовалось доказать Улыбаюсь
Спасибки.
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines