NullReferenceException

NullReferenceException

也许我做错了什么,但是由于某种原因,此代码总是由于NullReferenceException崩溃:

public class IncomingMessageEventData : EventArgs
{
    public IncomingMessageEventData(SpecialClasses.IncomingMessageData _msg, List<string> _toreturn)
    {
        msg = _msg;
        ToReturn = _toreturn;
    }
    public SpecialClasses.IncomingMessageData msg { get; set; }
    public List<string> ToReturn { get; set; }
}
public delegate void IncomingMessageHook(IncomingMessageEventData Args);
public event IncomingMessageHook InComingMessage;
public string NewMessage(string[] _message, System.Net.IPEndPoint RemoteIP)
{
    if (InComingMessage != null)
    {
        IncomingMessageEventData data = new IncomingMessageEventData(new SpecialClasses.IncomingMessageData(_message, RemoteIP), new List<string>());
        string ToReturn = "";
        InComingMessage(data);
        foreach (var item in data.ToReturn)
        {
if (item.Length > 0)
    ToReturn = item;
        }
        return ToReturn;
    }
    else return null;
}


有两种同时挂接到事件的方法,这可能是原因吗?如果是这样,如何避免呢?还是传递引用列表不是从挂钩方法获取值的方法吗?

谢谢!

编辑:更新了代码。现在哪个有效! ...我想我知道我做错了什么。

看,该程序是使用通过反射加载的插件的一部分,并且可能在调试之前我几乎没有忘记将更新的插件dll复制到插件目录的可能性。 ..呵呵。 ^^;
抱歉!但是,至少现在我的代码使用了最佳实践; P非常感谢您提供的最佳实践,我将其标记为答案!

最佳答案

这里有多个问题。

传递List<T>作为ref参数不是一个好方法。仅使用类型上已有的标准List<T> / ref方法,就可以修改out而不涉及Add / Remove

您正在使用非标准形式的事件处理程序。坚持使用EventHandler<TEventArgs>是更常规的做法,其中TEventArgs是源自EventArgs的某个类。从事件处理程序来回传递的数据应使用自定义EventArgs类上的属性或方法进行处理。

您的事件处理程序逻辑不是线程安全的。您需要捕获事件处理程序的本地副本,以解决有人在执行空值检查后立即取消订阅的情况。这是典型的模式:

// Capture the handler in a local
EventHandler<MyEventArgs> handler = this.MyEvent;
if (handler != null)
{
    // Invoke using the local copy
    handler(this, new MyEventArgs(/* ... */));
}

关于c# - 即使设置了变量,也会导致NullReferenceException,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8640175/

10-11 11:35