NullReferenceException 是谁的错?

发布于 2024-09-04 05:21:05 字数 979 浏览 10 评论 0原文

我目前正在开发一个通过属性公开内部列表的类。该清单应当并且可以修改。问题是,内部列表中的条目可以从类外部设置为 null。

我的代码实际上如下所示:

class ClassWithList
{
    List<object> _list = new List<object>();

    // get accessor, which however returns the reference to the list,
    // therefore the list can be modified (this is intended)
    public List<object> Data
    {
        get
        {
            return _list;
        }
    }

    private void doSomeWorkWithTheList()
    {
        foreach(object obj in _list)
            // do some work with the objects in the list without checking for null.
    }
}

所以现在在 doSomeWorkWithTheList() 中,我总是可以检查当前列表条目是否为空,或者我可以假设使用此类的人没有将条目设置为空的好主意。

所以最终问题是:在这种情况下,NullReferenceException 是谁的错?是类开发人员没有检查所有内容是否为 null 的错误(这通常会使代码 - 不仅在此类中 - 更加复杂),还是此类用户的错误,因为将 List 条目设置为 null 不会真的有道理吗?除非在一些非常特殊的情况下,我通常不会检查 null 值。这是一种糟糕的风格还是事实上的标准/实践标准?

我知道这个问题可能没有最终的答案,我只是缺少足够的经验来处理此类事情,因此想知道其他开发人员对此类情况的看法,并想听听在检查 null (或不)方面实际做了什么。

I'm currently working on a class which exposes an internal List through a property. The List shall and can be modified. The problem is, entries in the internal list could be set to null from outside the class.

My code actually looks like this:

class ClassWithList
{
    List<object> _list = new List<object>();

    // get accessor, which however returns the reference to the list,
    // therefore the list can be modified (this is intended)
    public List<object> Data
    {
        get
        {
            return _list;
        }
    }

    private void doSomeWorkWithTheList()
    {
        foreach(object obj in _list)
            // do some work with the objects in the list without checking for null.
    }
}

So now in the doSomeWorkWithTheList() I could always check whether the current list entry is null or I could just asume that the person using this class doesn't have the great idea to set entries to null.

So finally the questions end up in: Whose fault is a NullReferenceException in this case? Is it the fault of the class developer not checking everything for null (which would make code generally - not only in this class - more complex) or is it the fault of the user of this class, as setting a List entry to null doesn't really make sense? I'd tend to generally not check values for null except in some really special cases. Is this a bad style or de facto standard / standard in praxis?

I know there's probably no ultimate answer for this, I'm just missing enough experience for such thing and therefore wondering what other developers think about such cases and want to hear what's done in reality about checking null (or not).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

嘦怹 2024-09-11 05:21:05

如果公开该列表,则允许类的用户随意添加 null 引用。
如果您允许用户随意添加 null 引用,则您的类需要为列表中的 null 引用做好准备。

private void doSomeWorkWithTheList()
{
    foreach(object obj in _list)
        if (obj != null)
           // do some work with the object
}

如果您不喜欢这样,请不要公开列表(应该公开为 IList 顺便说一句),而是返回一个不允许 null< 的类似列表的集合/code> 要添加的引用。

If you expose the list, you allow the user of your class to add null references at will.
If you allow users to add null references at will, your class needs to be prepared for null references in the list.

private void doSomeWorkWithTheList()
{
    foreach(object obj in _list)
        if (obj != null)
           // do some work with the object
}

If you don't like that, don't expose the list (which should be exposed as IList<T> btw) but return a list-like collection that doesn't allow null references to be added.

停顿的约定 2024-09-11 05:21:05

很抱歉直言不讳,但如果你的代码不优雅地失败了,那是你的错。如果您的代码的其余部分有此要求,您封装该列表并公开一个空检查添加方法怎么样?也许您的类可以实现IList,并在内部存储您要处理的列表 - 然后在Add方法中,您只需抛出NullArgumentException > 或忽略 null 并继续...

Sorry to be blunt, but if your code falls over inelegantly, it's your fault. How about you encapsulate the list, and expose a null-checking add method if the rest of your code has this requirement? Maybe your class could implement IList, and internally store the list you are going to process - then in the Add method, you just either throw a NullArgumentException or ignore the null and continue...

关于从前 2024-09-11 05:21:05

使用 Collection,它是 List的内置可定制包装器。然后,您可以重写 InsertItem 和 SetItem,并在该项为 null 时抛出异常。

Use Collection<T>, it is built-in customisable wrapper for List<T> you can then override InsertItem and SetItem and throw an exception if the item is null.

玩世 2024-09-11 05:21:05

如果列表中允许 null,那么您需要检查它们。如果你想在这里指定“责任”,那么责任就是这个类,而不是该类的用户。通过一些 getter 和 setter 可以很简单地防止 null 进入列表(如果它们不属于列表)。

If you allow nulls inside the list, then you need to check for them. IF you want to assign "blame" here, then it's this class, not the users of the class. It would be simple via some getters and setters to prevent null from every making it into the list if they didn't belong in it.

请你别敷衍 2024-09-11 05:21:05

如果将 List 设置为 NULL 对于类的使用没有意义,则错误在于类设计者,他负责阻止对类进行该操作。

If setting the List to NULL does not make sense for the use of the class, then the fault lies with the class designer, who is responsible for preventing that operation on the class.

2024-09-11 05:21:05

这取决于您想要对 doSomeWorkWithTheList() 中的列表执行的操作以及如果值为 null 时您将执行的操作。

我要么检查 null 并自己抛出异常(带有诸如“无效列表值,不允许 null”之类的消息),要么通过创建抛出异常的 Collection 子类来不允许 null 值如果有人使用带有空值的 AddItem。

通过提供 API,您还提供了一份合同。如果合同规定“不允许空值”,那么 API 用户有责任不将任何内容设置为空,并且您有责任确保遵守合同。

This depends on what you want to do with the list in the doSomeWorkWithTheList() and what you would do if a value is null.

I would either check for null and throw an Exception myself (with a message like "Invalid List Value, null is not allowed") or not allow null values by creating a subclass of Collection<> which throws if someone uses AddItem with a null value.

By providing the API you also provide a contract. If the contract says "null values are not allowed" then it's the responsibility of the user of your API not to set anything to null and your responsibility to make sure the contract is followed.

最笨的告白 2024-09-11 05:21:05

如果您不希望列表中出现空值,那么您将在某个地方抛出异常。问题是:在哪里?当用户尝试添加到列表时或当您尝试处理它时?

我会在类的使用者尝试添加到列表时抛出一个 ArgumentException ,因为如果您无论如何都无法使用该项目,那么允许他们添加该项目有什么意义。但你会想抛出一个异常。不要让消费者仅仅因为没有得到其他通知就认为一切正常。

If you don't want nulls in the list, you're going to throw an exception somewhere. The question is: where? When the user is trying to add to the list or when you're trying to process it?

I would throw a ArgumentException at the point the consumer of the class was trying to add to the list, as what is the point of allowing them to add the item if you can't work with it anyway. But you will want to throw an exception. Don't let the consumer assume everything worked merely because they weren't informed otherwise.

無處可尋 2024-09-11 05:21:05

仅仅过滤列表以避免 NRE 是不好的做法,它隐藏了客户端代码中的错误。如果没有任何好的方法来诊断原因,代码必然会出现故障。让它爆炸。

公开一个集合对象供客户端代码参与也不是一个很好的做法。从 IList派生您的类(它必须是对象吗?)。您将 IList 的方法委托给类中的私有 List字段。但是您可以重写索引器并实现 Add 方法来验证客户端代码没有将空值放入集合中。如果真的有必要的话。

Just filtering the list to avoid NREs is bad practice, it hides bugs in the client code. The code is bound to malfunction without any good way to diagnose why. Let it bomb.

Exposing a collection object for the client code to party on isn't a very good practice either. Derive your class from IList<object> (does it have to be object?). You'll delegate the IList's methods to a private List<object> field in your class. But you can override the indexer and implement the Add method to verify that the client code isn't putting nulls in the collection. If that's really necessary.

像极了他 2024-09-11 05:21:05

您不应该相信用户不会做这样的事情。有时列表条目会被设置为空。这些事情都会发生。只要有可能,我就会尝试抓住它。如果公开列表,则始终有可能发生空引用,因此您应该考虑到这一点。

这不是你的错,但不管这是否真的是用户的错——你都会受到指责。

You shouldn't trust a user not to do something like this. Sometimes a list entry will get set to null. These things happen. I would try and catch it whenever possible. If you expose the list there is always a posibility that a null reference will occur, so you should account for this.

Its not your fault as such, but it doesn't matter whether its actually the user's fault - you will be blamed.

走野 2024-09-11 05:21:05

这是试图使用该列表的人的错。您始终必须假设它可能为空,因此您应该检查它。

这涉及防御性编程以及如何保护您的代码免受其他人的侵害。

第 8 章中的代码完整介绍了这个概念。

It's the fault of the person who's trying to use the List. You always have to assume that it could be null and so you should check for it.

This goes into Defensive Programming and how you have to protect your code from what other people do.

Code Complete in Chapter 8 goes into this concept.

夜清冷一曲。 2024-09-11 05:21:05

添加代码合同。然后,您可以在方法开始、返回值以及整个过程中使用不变检查来检查空值。然后,根据您拥有的 Visual Studio 版本,您可以在编译时和运行时进行检查。

Add code contracts. Then you can check for nulls at method start, return value and through out using invariant checking. Then depending on what version of visual studio you have, you can check at compile time and run time.

旧伤慢歌 2024-09-11 05:21:05

我真的不喜欢将空值插入到数组以外的任何类型的集合中。

看来我和这里的很多海报不同。对我来说,任何将 null 插入作为其他对象属性的集合中的人都应该得到他以后得到的东西。

当我编写自定义哈希表时(System.Generic.Dictionary 有一些问题,我不会在这里讨论),我决定让查找在未找到时返回 null。由于我不插入空值,这让我的生活更轻松。

I really do not like inserting nulls into collections of any kind other than arrays.

It seems I differ with a lot of posters here. To me, anybody who sticks a null into a collection that is a property of some other object deserves what he gets later on.

When I coded my custom hashtable (System.Generic.Dictionary has some problems I won't go into here) I decided to make lookup return null on not found. Since I don't insert nulls this made my life easier.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文