Вызов события внутри класса и использование обработчика для другого класса - PullRequest
1 голос
/ 08 декабря 2011

Я создаю библиотеку классов и использую ее в программе Windows Form. Я хотел бы обработать событие этой библиотеки внутри программы. Я использую этот код:

Класс внутри библиотеки:

public class KSEDataServIO
{
    public delegate void IsReadyForUseEventHandler(object sender, IsReadyForUseEventArgs e);
    public event IsReadyForUseEventHandler IsReadyForUse;
    public KSEDataServIO(){
       EvArg = new IsReadyForUseEventArgs("AuthOkay");
       IsReadyForUse(this, EvArg); //This is where i get the issue.
    }
}

И, в форме окна я делаю это:

private void button1_Click(object sender, EventArgs e) {
            KSEDataServIO con = new KSEDataServIO();
            con.IsReadyForUse += new KSEDataServIO.IsReadyForUseEventHandler(con_IsReadyForUse);
}

void con_IsReadyForUse(object sender, IsReadyForUseEventArgs e)
{
     MessageBox.Show(e.Etat);
}

Я получил NullReferenceException для строки 'IsReadyForUse (this, EvArg); внутри библиотеки классов. Есть идеи?

Ответы [ 2 ]

2 голосов
/ 08 декабря 2011

Ваша проблема в том, что вы вызываете событие внутри конструктора KSEDataServIO. В этот момент ничто не подписалось на этот обработчик событий, и поэтому оно вызывает исключение нулевой ссылки.

Итак, одна вещь - правильно вызвать обработчик событий, для которого этот шаблон обычно используется:

public delegate void IsReadyForUseEventHandler(object sender, IsReadyForUseEventArgs e);
public event IsReadyForUseEventHandler IsReadyForUse;

void OnIsReadyForUse(IsReadyForUseEventArgs e)
{
    var handler = IsReadyForUse;
    if (handler != null)
    {
        handler(this, e);
    }
}

Затем используйте это, чтобы поднять событие:

OnIsReadyForUse(new IsReadyForUseEventArgs("AuthOkay"))

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

Также вы должны выставить свойство IsReady в вашем классе. Поэтому, если пользователь приходит позже, он может запросить объект, если он уже готов. Если событие IsReady уже возникло, когда вы начали использовать объект где-то, в противном случае вы можете пропустить событие.

Редактировать : Вы можете передать обработчик конструктору, если действительно хотите это сделать:

public KSEDataServIO(IsReadyForUseEventHandler handler)
{
   IsReadyForUse += handler;
   OnIsReadyForUse(new IsReadyForUseEventArgs("AuthOkay")); // see pattern above
}

Однако, поскольку ваше событие предоставляет this в качестве отправителя, вы передаете ссылку на объект до того, как он завершит выполнение всего конструктора, что может привести к проблемам, которые трудно отследить. Если единственное место, где вы когда-либо собирались вызвать событие, это конец конструктора, тогда он вам на самом деле не нужен.

0 голосов
/ 08 декабря 2011

Вы вызываете событие в конструкторе, прежде чем назначить con_IsReadyForUse.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...