Собитие + делегат. Некоторые аспекты. Тока ногами не бейте
От: m_CodeTyper Молдова  
Дата: 20.10.05 06:34
Оценка:
Дано:

1.
Класс типа CApp, в котором создаются объекты классов типа CDBCRM и CForm:

public class CApp
{
    private static CDBCRM m_DBCRM;
    private static CForm m_frmMain;
//... и т.п.
}


Класс CDBCRM представляет функции работы с БД ну а форма — понятно...

2.
В классе CDBCRM интерес представляет поле m_Connection:


public class CDBCRM
{
...
    public SqlConnection    m_Connection;
...
}


3.
Есть необходимость обрабатывать событие m_Connection.StateChange. Тогда появляется следующее:

public class CDBCRM
{
...
   //конструктор
   public CDBCRM()
   {
       m_Connection = new SqlConnection();
       m_Connection.StateChange += new StateChangeEventHandler(OnStateChange);
   }

   // и далее по ходу

   public delegate void ConnectionEventHandler(object sender, StateChangeEventArgs e);
   public static event ConnectionEventHandler ConnectionStateChange;
   private void OnStateChange(object sender, StateChangeEventArgs e)
   {
       if (ConnectionStateChange != null)
              ConnectionStateChange(sender, e);
   }
...
}


В конструкторе класса CApp соответственно вешаем приемник события ConnectionStateChange

CDBCRM.ConnectionStateChange += new CDBCRM.ConnectionEventHandler(frmMain.OnCRMStateChange);


а в форме соответственно:

public void OnCRMStateChange(object sender, StateChangeEventArgs e)
{
    //do some work
}


Вопросы:

1.
Имею я право сделать так:

public class CDBCRM
{
   public event ConnectionEventHandler ConnectionStateChange;
}

// и соответственно не

CDBCRM.ConnectionStateChange += new CDBCRM.ConnectionEventHandler(frmMain.OnCRMStateChange);

//a

m_DBCRM.ConnectionStateChange += new CDBCRM.ConnectionEventHandler(frmMain.OnCRMStateChange);


т.к. хочу обрабатывать это событие не на уровне типа, а на уровне объекта класса?
И так и так все работает просто кто-нить развейте сомнения

2.
Неужели так все сложно? В классе делегирующем обработчик на стандартное событие (m_Connection.StateChange)
перехватывать его (m_Connection.StateChange += new StateChangeEventHandler(OnStateChange)),
объявлять свое событие (public static event ConnectionEventHandler ConnectionStateChange) и выставлять его
и еще объявлять свой делегат (public delegate void ConnectionEventHandler(object sender, StateChangeEventArgs e)

Нельзя ли как-нить сразу связать событие m_Connection.StateChange
и обработчик public delegate void ConnectionEventHandler(object sender, StateChangeEventArgs e) ???

а m_Connection объявлять как public ох как не хотца.

В шарпе я недавно, так шо не бейте ногами

Thanks forward
Vad
Re: Собитие + делегат. Некоторые аспекты. Тока ногами не бей
От: Mab Россия http://shade.msu.ru/~mab
Дата: 20.10.05 08:49
Оценка:
Используйте теги c# и /с# для выделения кода на этом языке. Еще стоит отучаться писать C перед именами классов -- naming guidelines в .NET другие.

_CT>Имею я право сделать так:


_CT>
_CT>public class CDBCRM
_CT>{
_CT>   public event ConnectionEventHandler ConnectionStateChange;
_CT>}

_CT>// и соответственно не

_CT>CDBCRM.ConnectionStateChange += new CDBCRM.ConnectionEventHandler(frmMain.OnCRMStateChange);

_CT>//a

_CT>m_DBCRM.ConnectionStateChange += new CDBCRM.ConnectionEventHandler(frmMain.OnCRMStateChange);
_CT>


_CT>т.к. хочу обрабатывать это событие не на уровне типа, а на уровне объекта класса?

Событие было объявлено статическим. Поэтому второй способ даже не скомпилируется. Что подразумевается под "на уровне объекта класса"?

Вообще, зачем было делать событие статическим?

[Ужас поскипан]
Если нужно делегировать событие, то делают так:
public static event ConnectionEventHandler ConnectionStateChange
{
  add { m_Connection.ConnectionStateChange += value; }
  remove { m_Connection.ConnectionStateChange -= value; }
}


Кстати, зачем в CDBCRM был объявлен тип делегата, ничем не отличающийся от существующего, не ясно.
Re[2]: Собитие + делегат. Некоторые аспекты. Тока ногами не
От: m_CodeTyper Молдова  
Дата: 24.10.05 13:42
Оценка:
Здравствуйте, Mab, Вы писали:

Mab>Используйте теги c# и /с# для выделения кода на этом языке. Еще стоит отучаться писать C перед именами классов -- naming guidelines в .NET другие.


Спасибо — учту

_CT>>Имею я право сделать так:


_CT>>
_CT>>public class CDBCRM
_CT>>{
_CT>>   public event ConnectionEventHandler ConnectionStateChange;
_CT>>}

_CT>>// и соответственно не

_CT>>CDBCRM.ConnectionStateChange += new CDBCRM.ConnectionEventHandler(frmMain.OnCRMStateChange);

_CT>>//a

_CT>>m_DBCRM.ConnectionStateChange += new CDBCRM.ConnectionEventHandler(frmMain.OnCRMStateChange);
_CT>>


_CT>>т.к. хочу обрабатывать это событие не на уровне типа, а на уровне объекта класса?

Mab>Событие было объявлено статическим. Поэтому второй способ даже не скомпилируется. Что подразумевается под "на уровне объекта класса"?

Во втором варианте оно уже не было статическим

Mab>Вообще, зачем было делать событие статическим?


В примерах видел. Затрудняюсь ответить

Mab>[Ужас поскипан]

Mab>Если нужно делегировать событие, то делают так:
Mab>
Mab>public static event ConnectionEventHandler ConnectionStateChange
Mab>{
Mab>  add { m_Connection.ConnectionStateChange += value; }
Mab>  remove { m_Connection.ConnectionStateChange -= value; }
Mab>}
Mab>


Не компилируется. App.CDBCRM.m_Connection' denotes a 'field' where a 'class' was expected




Mab>Кстати, зачем в CDBCRM был объявлен тип делегата, ничем не отличающийся от существующего, не ясно.


Где?

Весь и прикол, чтобы делегировать обработчик события OnStateChange стандартного класса (типа SQLConnection) наверх, не открывая при этом самого m_Connection.

Или я не догоняю
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Vad
Re[3]: Собитие + делегат. Некоторые аспекты. Тока ногами не
От: Mab Россия http://shade.msu.ru/~mab
Дата: 24.10.05 14:14
Оценка:
Здравствуйте, m_CodeTyper, Вы писали:

Mab>>[Ужас поскипан]

Mab>>Если нужно делегировать событие, то делают так:
Mab>>
Mab>>public static event ConnectionEventHandler ConnectionStateChange
Mab>>{
Mab>>  add { m_Connection.ConnectionStateChange += value; }
Mab>>  remove { m_Connection.ConnectionStateChange -= value; }
Mab>>}
Mab>>


_CT>Не компилируется. App.CDBCRM.m_Connection' denotes a 'field' where a 'class' was expected

Прошу прощения, static там лишний, конечно. Нужно просто public event.

_CT>Где?

public class CDBCRM
{
...
   public delegate void ConnectionEventHandler(object sender, StateChangeEventArgs e);
 
}
Re[3]: Собитие + делегат. Некоторые аспекты. Тока ногами не
От: Andrbig  
Дата: 24.10.05 14:17
Оценка: +1
Здравствуйте, m_CodeTyper, Вы писали:

Mab>>Вообще, зачем было делать событие статическим?


_CT>В примерах видел. Затрудняюсь ответить


Статические события — для статических функций. А серьезно, лучше не плодить статику, а сделать синглетон.

_CT>Весь и прикол, чтобы делегировать обработчик события OnStateChange стандартного класса (типа SQLConnection) наверх, не открывая при этом самого m_Connection.

public class myConnection
{
    private SqlConnection _connection;

    public event StateChangeEventHandler StateChange
    {
        add { _connection.StateChange += value; }
        remove { _connection.StateChange -= value; }
    }
}
Re[4]: Собитие + делегат. Некоторые аспекты. Тока ногами не
От: m_CodeTyper Молдова  
Дата: 31.10.05 07:47
Оценка:
Спасибо всем. Уразумили. Все получилось красяво.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Vad
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.