我似乎陷入了 NullReferenceExceptions 的巨大麻烦

发布于 2024-09-08 17:02:20 字数 839 浏览 5 评论 0原文

最近我正在开发一个软件,可以解析并显示网站上的 XML 信息。够简单吧?

我收到大量 NullReferenceExceptions。例如,这个方法:

private void SetUserFriends(List<Friend> list)
{
    int x = 40;
    int y = 3;

    if (list != null)
    {
        foreach (Friend friend in list)
        {
            FriendControl control = new FriendControl();
            control.ID = friend.ID;
            control.URL = friend.URL;
            control.SetID(friend.ID);
            control.SetName(friend.Name);
            control.SetImage(friend.Photo);

            control.Location = new Point(x, y);
            panel2.Controls.Add(control);

            y = y + control.Height + 4;
        } 
    }
}

我必须在实际的 foreach 循环周围包装一个丑陋的 sin If 以防止异常。

我觉得我只是在泄气的轮胎上贴上创可贴,而不是真正解决问题。我有什么办法可以解决这个问题吗?也许我应该读一本关于编程模式或其他什么的书?

真的,我迷路了。我可能问错了问题。

Recently I'm developing a software that parses and displays XML information from a website. Simple enough right?

I'm getting LOADS of NullReferenceExceptions. For example, this method:

private void SetUserFriends(List<Friend> list)
{
    int x = 40;
    int y = 3;

    if (list != null)
    {
        foreach (Friend friend in list)
        {
            FriendControl control = new FriendControl();
            control.ID = friend.ID;
            control.URL = friend.URL;
            control.SetID(friend.ID);
            control.SetName(friend.Name);
            control.SetImage(friend.Photo);

            control.Location = new Point(x, y);
            panel2.Controls.Add(control);

            y = y + control.Height + 4;
        } 
    }
}

I had to wrap an ugly as sin If around the actual foreach loop in order to prevent an exception.

I feel I'm just putting bandaids on a flat tire instead of actually fixing the problem. Is there any way I can tackle this problem? Maybe a book I should read regarding programming patterns or what not?

Really, I'm lost. I'm probably asking the wrong questions.

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

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

发布评论

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

评论(6

当爱已成负担 2024-09-15 17:02:20

听起来好像您不确定如果您的方法中收到错误的参数该怎么办。您现在所做的事情本质上没有任何问题,但更常见的模式是检查方法头部的参数,如果它们不是您所期望的,则抛出异常:

if (list == null)
{
    throw new ArgumentNullException(list);
}

这是一种常见的防御性编程模式 -检查以确保您提供的数据通过基本的健全性检查。

现在,如果您自己显式调用此方法,并且发现此方法在您不期望的情况下接收到 null list 参数,那么是时候查看调用方法的逻辑了。我自己,当我没有元素时,我更喜欢传递一个空列表,而不是 null,以避免此类特殊情况。

It sounds as if you're unsure what to do if you receive bad parameters in your methods. There's nothing inherently wrong with what you're doing now, but the more common pattern is to check parameters in the head of your method, throwing an exception if they're not what you're expecting:

if (list == null)
{
    throw new ArgumentNullException(list);
}

This is a common defensive programming pattern - check to make sure that the data you're provided passes basic sanity checks.

Now, if you're calling this method explicitly yourself, and you're finding this method receiving a null list parameter when you're not expecting it, it's time to look at the logic of the calling method. Myself, I prefer to pass an empty list when I have no elements, as opposed to null, to avoid special cases such as this.

沉鱼一梦 2024-09-15 17:02:20

我可能会被“无多重退出”人群否决,但我通常会在方法开始时通过简单的检查来处理这个问题:

if (list == null || list.Count == 0) return;

这指定了退出条件,然后您无需担心多个级别你的方法中的缩进。仅当您能够接受列表为空或为空的事实时,这才有效 - 在某些情况下可能会发生这种情况。

但我同意 codeka 的观点,因为你需要查看调用代码并确定是否可以从那里改进它。

I'm probably going to get downvoted by the "no multiple exit" crowd but I usually handle that with a simple check right at the beginning of the method:

if (list == null || list.Count == 0) return;

this specifies the exit conditions and then you don't need to worry about multiple levels of indentation in your method. This only works if you can afford to swallow the fact that your list is null or empty - which can happen in some cases.

But I agree with codeka, in that you need to look at the calling code and work out if you can improve it from there.

旧城烟雨 2024-09-15 17:02:20

看起来防御性编程和参数验证正是您正在寻找的。

正如其他人所说,简单的参数验证对您有用:

if (list == null)
    throw new ArgumentNullException("list");

或者,如果您厌倦了不断为每个参数编写这样的检查,您可以查看许多开源 .NET 前提条件执行库之一。我喜欢 CuttingEdge.Conditions

这样,您可以使用如下所示的内容:

Condition.Requires(list, "list").IsNotNull();

但是,设置像上述任一这样的前提条件只会指定您的方法不接受空值。 您的问题仍然存在,因为您将空值传递到方法中!要解决这个问题,您必须检查是什么在调用您的方法,并找出为什么要传入空对象。

It seems like defensive programming and parameter validation is what you're looking for.

As others have said, simple parameter validation would work for you:

if (list == null)
    throw new ArgumentNullException("list");

Alternatively, if you tire of constantly writing checks like this for each parameter, you could check out one of the many open source .NET precondition enforcement libraries. I am fond of CuttingEdge.Conditions.

That way, you can use something like this:

Condition.Requires(list, "list").IsNotNull();

However, setting up a precondition like either of the above will just specify that your method does not accept nulls. Your problem will still exist in that you are passing nulls into the method! To fix that, you will have to examine what is calling your methods, and working out why null objects are being passed in.

人│生佛魔见 2024-09-15 17:02:20

除了抛出 ArgumentNullException 异常之外,还有一种称为“Null Obejct Pattern”的东西,如果您想要传递 null,则可以使用它来指示某些东西不存在,例如,但不想显式检查空值。本质上,它是一个实现相同接口的存根类,但它的方法通常要么是空的,要么返回足以使它们变得复杂的值。
http://en.wikipedia.org/wiki/Null_Object_pattern

对于可以不能轻易地通过不能为空来表达它们的不存在。

As well as throwing ArgumentNullException exceptions there's also something called the "Null Obejct Pattern" which you can use if you want to be passing around a null, to indicate, for example, that something doesn't exist, but don't want to have to explicitly check for nulls. Essentially it's a stub class that implements the same interface, but its methods are usually either empty or return just enough to make them comple.
http://en.wikipedia.org/wiki/Null_Object_pattern

Also useful for value types that can't easily express their non existence, by not being able to be null.

苏佲洛 2024-09-15 17:02:20

当给出无效输入时,我会提前返回(或提前抛出 InvalidArgumentException)。

例如:

private void SetUserFriends(List<Friend> list) 
{ 
    if (list == null) 
        return;

    /* Do stuff */
}

或者,您可以使用通用的空合并模式:

private void SetUserFriends(List<Friend> list) 
{ 
    list = list ?? new List<Friend>();

    /* Do Stuff */
}

I would return early (or throw an InvalidArgumentException early) when given invalid input.

For example:

private void SetUserFriends(List<Friend> list) 
{ 
    if (list == null) 
        return;

    /* Do stuff */
}

Alternatively you can use the general null coalescing pattern:

private void SetUserFriends(List<Friend> list) 
{ 
    list = list ?? new List<Friend>();

    /* Do Stuff */
}
紅太極 2024-09-15 17:02:20

你确实问错了问题。正确的问题是“null 是否代表无效输入或表示 X 的标志”。

在将非空引用类型添加到语言中并使其成为各种 API 之前,您可以选择在代码中明确说明这一点,或者让空引用异常帮助您找到违反期望的位置,然后修复数据/代码之一方式或其他方式。

You are indeed asking the wrong question. The right question is "does null represent an invalid input or a flag that means X".

Until non-null reference types are added to the language and make their way various API's, you have the choice of making that explicit in the code or letting null reference exceptions help you find where the expectation is violated and then fixing the data/code one way or another.

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