Вопрос о делегате - PullRequest
       6

Вопрос о делегате

3 голосов
/ 27 января 2012

Я новичок в разработке c #. Я просто пытаюсь изучить функцию делегата. Основываясь на статьях и заметках о делегатах, которые я читал, я попытался написать пример кода для реализации делегата на основе того, что я понял из этих заметок и статей.

Но я получаю сообщение об ошибке при запуске образца

"Ссылка на объект не установлена ​​для экземпляра объекта."

В чем здесь проблема? или я правильно реализовал делегата? или моя концепция о делегате неверна? ..

Пожалуйста, помогите. Заранее спасибо.

Я разместил свой код ниже.

Default.aspx.cs

public partial class _Default : System.Web.UI.Page
{
    TestClass myObject = new TestClass();

    protected void Page_Load(object sender, EventArgs e)
    {
        myObject.MyDelegateEvent += new TestClass.MyDelegate(myObject_MyDelegateEvent);
    }

    void myObject_MyDelegateEvent(object sender, EventArgs e)
    {
        Console.WriteLine("Delegate event called");
    }
}

TestClass

public class TestClass
{
    public delegate void MyDelegate(object sender, EventArgs e);

    public event MyDelegate MyDelegateEvent;

    public TestClass()
    {       
        MyDelegateEvent(this, null); // Here getting error "Object reference not set to an instance of an object."

    }

}

Ответы [ 4 ]

6 голосов
/ 27 января 2012

То, что вы пытаетесь сделать, это: вызвать событие в самом конструкторе, то есть в то время, когда для вашего события нет подписчика, следовательно, MyDelegateEvent имеет значение null.

Лучший вариант - обнулить проверку перед тем, как вызвать событие

//Check for not null
if(MyDelegateEvent != null)
{
    MyDelegateEvent(this, null);
}
1 голос
/ 27 января 2012

Когда вы объявляете событие, оно инициализируется как null. Итак, в вашем конструкторе TestClass вы пытаетесь вызвать событие, но так как событие null, это вызывает NullReferenceException, который вы видите.

Чтобы избежать этого, вам нужно зарегистрировать обработчик события или проверить нулевое значение, прежде чем вызывать событие:

if (MyDelegateEvent != null)
{
    MyDelegateEvent(...)
}

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

public event MyDelegate MyDelegateEvent = delegate {}; // registers a delegate that does nothing
1 голос
/ 27 января 2012

Всегда проверяйте на ноль перед возбуждением события:

if (this.MyDelegateEvent != null)
{
     // Raises the event here
}

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

EDIT: Для полноты, когда аргумент события не используется, вы должны использовать EventArgs.Empty вместо null:

if (this.MyDelegateEvent != null)
{
    this.MyDelegateEvent(this, EventArgs.Empty);
}

Также существует делегат EventHandler , который можно использовать, если не указан аргумент события. Это полезно, так как вам не нужно каждый раз писать свое.

0 голосов
/ 27 января 2012

Незначительное замечание по поводу некоторого кода выше. Для MyDelegateEvent возможно изменение между проверкой и использованием. Рекомендуемая форма (Руководство по проектированию рамок) соответствует

var del = MyDelegateEvent;
if (del != null) {
    del(...);
}

чч,
Алан.

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