触发事件时NullReferenceException

Sku*_*udd 19 c# sockets events event-handling

考虑以下:

class Client
{
    public static event EventHandler connectFailed;

    private Socket socket;

    public Client()
    {
        socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        IPEndPoint endpoint = new IPEndpoint(
            IPAddress.Parse("192.168.1.100"),
            7900
            );

        try
        {
            socket.Connect(endpoint);
        }
        catch(Exception e)
        {
            connectFailed(e, new EventArgs());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

假设其余代码已实现(事件处理程序等在Program.cs中).

我遇到的问题与NullRefrerenceExceptionconnectFailed(e, new EventArgs());线了,我不明白为什么.我所有的其他事件都很好,但我不知道这有什么不同.

有任何想法吗?

Ran*_*832 29

你需要一个空的检查 - 在C#中,当没有在该事件上注册处理程序时,你无法调用事件.

通常的做法是实现OnConnectFailed方法:

protected virtual void OnConnectFailed(e as EventArgs) {
    EventHandler tmp = connectFailed;
    if(tmp != null)
        tmp(this,e);
}
Run Code Online (Sandbox Code Playgroud)

此外,事件处理程序的第一个参数应该是this,而不是异常.如果需要将异常传递给事件处理程序,请创建一个EventArgs带有exception属性的类.

此外,从构造函数中引发事件没有意义......没有机会为它添加处理程序.

  • 关键是最后一句,在构造函数完成之前没有任何东西可以订阅事件.您应该重构连接代码并使其成为名为Connect()的方法. (2认同)

Hos*_*Rad 9

同样在C#6中,您可以通过以下方式进行null检查:

connectFailed?.Invoke(this, e); 
Run Code Online (Sandbox Code Playgroud)


Swa*_*Jat 7

找到了,

public delegate void OnRequestReceivedHandler(object sender);
public event OnRequestReceivedHandler ReqeustReceived = delegate { };
Run Code Online (Sandbox Code Playgroud)