在C#中引发事件时出现空引用异常

时间:2017-05-26 12:30:01

标签: c# vb.net events

对于遵循VB.Net代码的等效C#代码是什么:

Public Event EndOfVideo()

Private Sub RaiseEndOfVideo()
        RaiseEvent EndOfVideo()
End Sub

修改

这是telerik转换器为我生成的等效C#代码。

public event EndOfVideoEventHandler EndOfVideo;
public delegate void EndOfVideoEventHandler();

private void RaiseEndOfVideo()
{
    if (EndOfVideo != null) {
        EndOfVideo();
    }
}

调用RaiseEndOfVideo不会触发/调用EndOfVideo事件,并引发Null Reference Exception。

3 个答案:

答案 0 :(得分:2)

考虑您有一个活动VideoPlayer的班级EndOfVideo,并且您希望举起此活动,并且有人在EndVideo的对象上调用方法VideoPlayer

现在,像类事件的任何其他成员一样,也初始化为null并在附加某个处理程序时获取值。

使用+=运算符附加事件处理程序。

public class VideoPlayer
{
    public event EndOfVideoEventHandler EndOfVideo;
    // Following delegate indicates that the a method accepting no parameter
    // and returning void can be attached as an handler to this event.
    public delegate void EndOfVideoEventHandler();

    public void EndVideo()
    {
        RaiseEndOfVideo();
    }

    private void RaiseEndOfVideo()
    {
        if (EndOfVideo != null)
        {
            // Following line of code executes the event handler which is 
            // attached to the event.
            EndOfVideo();
        }
    }
}

public class WebPage
{
    public void VideoStopped()
    {
        Console.WriteLine("Video Stopped");
    }
}

现在使用Main

program.cs方法
static void Main(string[] args)
{
    VideoPlayer player = new VideoPlayer();
    WebPage page = new WebPage();

    player.EndOfVideo += page.VideoStopped;

    // Following method call on player object will call internally 
    // RaiseEndOfVideo  which will Raise event and event will execute 
    // VideoStopped method of page object which is attached in previous line 
    // and display "Video Stopped" message in Console.
    player.EndVideo();

    Console.WriteLine("Completed!!! Press any key to exit");
    Console.ReadKey();
}

我希望这可以帮助您开始了解事件和代理如何在C#中工作。如需进一步阅读,您可以通过https://msdn.microsoft.com/en-us/library/edzehd2t(v=vs.110).aspx

答案 1 :(得分:1)

这是编写没有参数的事件的普遍接受的方式:

public class Foo
{
    public event EventHandler EndOfVideo;

    protected virtual void OnEndOfVideo()
    {
        var handler = EndOfVideo;
        if (handler != null)
            handler(this, EventArgs.Empty);
    }
}

您的代码是过去所需要的:创建代表和yada yada。

说明显而易见,您需要订阅来举办以下活动:

public class Bar
{
    public void DoAllTheThings()
    {
        var foo = new Foo();
        foo.EndOfVideo += foo_EndOfVideo;
    }

    void foo_EndOfVideo(object sender, EventArgs e)
    {
        Console.WriteLine("EndOfVideo");
    }
}

为了完整起见,EventHandler委托有一个通用副本EventHandler<T>,当你想要一个有参数的事件时,你会使用它,T应该是一个继承自System.EventArgs的类,它包含您希望事件公开的信息。

答案 2 :(得分:0)

为此,您需要创建一个自定义eventHandler来指定事件处理程序的方法签名