如果对象为空,我想防止对其进行进一步处理。

在下面的代码中,我检查对象是否为空:

if (!data.Equals(null))

and

if (data != null)

然而,我在datlist . add (data)收到一个NullReferenceException。如果对象为空,它甚至不应该输入If语句!

因此,我在问这是否是检查对象是否为空的正确方法:

public List<Object> dataList;
public  bool AddData(ref Object data)
    bool success = false;
    try
    {
        // I've also used "if (data != null)" which hasn't worked either
        if (!data.Equals(null))
        {
           //NullReferenceException occurs here ...
           dataList.Add(data);
           success = doOtherStuff(data);
        }
    }
    catch (Exception e)
    {
        throw new Exception(e.ToString());
    }
    return success;
}

如果这是检查对象是否为空的正确方法,那么我做错了什么(如何防止对对象进行进一步处理以避免NullReferenceException)?


当前回答

正如其他人已经指出的那样,它不是data,而是dataList是null。除此之外……

catch-throw is an antipattern that almost always makes me want to throw up every time that I see it. Imagine that something goes wrong deep in something that doOtherStuff() calls. All you get back is an Exception object, thrown at the throw in AddData(). No stack trace, no call information, no state, nothing at all to indicate the real source of the problem, unless you go in and switch your debugger to break on exception thrown rather than exception unhandled. If you are catching an exception and just re-throwing it in any way, particularly if the code in the try block is in any way nontrivial, do yourself (and your colleagues, present and future) a favor and throw out the entire try-catch block. Granted, throw; is better than the alternatives, but you are still giving yourself (or whoever else is trying to fix a bug in the code) completely unnecessary headaches. This is not to say that try-catch-throw is necessarily evil per se, as long as you do something relevant with the exception object that was thrown inside the catch block.

然后,首先就存在捕获Exception的潜在问题,但这是另一回事,特别是因为在这种特殊情况下,您抛出了一个异常。

另一件让我感到非常危险的事情是,数据可能在函数执行期间更改值,因为您是通过引用传递的。因此,null检查可能会通过,但在代码对值进行任何操作之前,它已经被更改了——可能是null。我不确定这是否值得关注(可能不是),但这似乎值得关注。

其他回答

你的dataList是空的,因为它还没有被实例化,从你发布的代码判断。

Try:

    public List<Object> dataList = new List<Object>();
    public  bool AddData(ref Object data)
    bool success = false;
    try
    {
        if (!data.Equals(null))   // I've also used if(data != null) which hasn't worked either
        {
           dataList.Add(data);                      //NullReferenceException occurs here
           success = doOtherStuff(data);
        }
    }
    catch (Exception e)
    {
        throw;
    }
    return success;
}

在c# >中使用if (obj是null)

非空用: c# 7-8: if (obj是对象) c# 9: if (obj不为空)

它们将忽略由对象定义的任何==或!=(当然,除非您想将它们用于空检查)

欲了解更多,请参阅c#语言参考,见is运算符。

不是data为空,而是dataList为空。

你需要创建一个

public List<Object> dataList = new List<Object>();

更好的是:既然它是一个字段,就把它设为私有。如果没有什么可以阻止你,也把它设置为只读。只是很好的练习。

一边

检查是否为空的正确方法是if(data != null)。这种检查对于引用类型是普遍存在的;even Nullable<T>重写了相等运算符,以更方便地表示Nullable。检查是否为null时使用HasValue。

如果你执行If (!data. equals (null)),那么如果data == null,你将得到一个NullReferenceException。这有点滑稽,因为避免这种异常是首要目标。

你也在这样做:

catch (Exception e)
{
    throw new Exception(e.ToString());
}

这绝对不好。我可以想象,您把它放在那里只是为了在仍然在方法内部的情况下进入调试器,在这种情况下忽略这段。否则,不要无缘无故地捕获异常。如果你这样做了,请使用throw;重新抛出它们。

本例中的问题不在于数据为空。那就是dataList本身是空的。

在声明dataList的地方,应该创建一个新的List对象并将其赋值给变量。

List<object> dataList = new List<object>();

从c# 8开始,你可以使用'empty'属性模式(带模式匹配)来确保对象不为空:

if (obj is { })
{
    // 'obj' is not null here
}

这种方法意味着“如果对象引用了某个对象的实例”(即它不是空的)。

你可以把它看作是:if (obj is null)....的对立面当对象没有引用某个对象的实例时,返回true。

有关c# 8.0模式的更多信息,请阅读这里。