如何错误处理 NullReferenceException

How to Error Handle a NullReferenceException

提问人:ToiletPainter 提问时间:8/7/2015 最后编辑:Huang ChenToiletPainter 更新时间:8/7/2015 访问量:788

问:

我的网站关闭了几天,因此我试图在 MVC 应用程序无法访问某些资源时产生一些错误处理,因此如果某些内容不再不可用,则整个事情不必关闭。

目前,控制器正在尝试访问不可用的 viewbag.moreNewProducts。

public ActionResult Index(string search)
    {
        string[] newProductLines = this.getMoreNewProducts();
        string[] newNews = this.getMoreNews();
        string[] newPromotions = this.getMorePromotions();
        string[] fewerProductLines = this.getLessNewProducts(newProductLines);
        ViewBag.moreNewProducts = newProductLines;
        ViewBag.moreNews = newNews;
        ViewBag.morePromotions = newPromotions;
        ViewBag.lessNewProducts = fewerProductLines;
        bool disableShowMore = false;

这是我遇到错误的地方:“foreach(newProductLines中的字符串行)”

public string[] getLessNewProducts(string[] newProductLines)
    {
        int charCount = 0;
        int arrayCount = 0;
        string[] displayProductLines = new string[6];
        bool continueWriting;

            if (newProductLines == null)
            {

                foreach (string line in newProductLines)
                {
                    continueWriting = false;
                    for (int i = 0; charCount < 250 && i < line.Length && arrayCount < 5; i++)
                    {
                        string index = newProductLines[arrayCount].Substring(i, 1);
                        displayProductLines[arrayCount] += index;
                        charCount++;
                        continueWriting = true;
                    }
                    if (continueWriting == true)
                    {
                        arrayCount++;
                    }
                }
                string[] LessNewProducts = new string[arrayCount];
                for (int d = 0; d < arrayCount; d++)
                {
                    LessNewProducts[d] = displayProductLines[d];
                }
                return LessNewProducts;

            }

            else
            {
                return null;
            }




    }

我如何绕过 if else 语句,以便整个事情不必崩溃?

ASP.NET-MVC-4 错误处理 NullReferenceException

评论

0赞 Jorge Y. C. Rodriguez 8/7/2015
你有没有试过把它包在试一试里面?

答:

0赞 alhola 8/7/2015 #1

if (newProductLines == null)

应替换为 if (newProductLines != null),这样您就不必将 newProductLines 的代码作为 null 进行处理。基本上,在这种情况下,除非您使用 try catch 块管理异常,否则您将始终拥有 NullReferenceException。

0赞 Speerian 8/7/2015 #2

两件事。

  1. 您的陈述有错误的条件。我不相信你想输入 if 为 null。您可以反转此条件以获得所需的结果()。if (newProductLines == null)newProductLinesif (newProductLines != null)

  1. 如果以后遇到需要捕获错误的另一种情况,则始终可以使用 try-catch 块来捕获预期的异常。

try
{
   //code that could cause the error here
}
catch(NullReferenceException nullRefExcep)
{
   //what you want it to do if the null reference exception occurs
}
0赞 StriplingWarrior 8/7/2015 #3

真正要问自己的问题是:

为什么会为 null?newProductLines

大概发现了一种情况,它认为返回一个值是合适的。getMoreNewProducts()null

如果发生这种情况是因为系统有一个错误,使你的页面变得毫无意义,那么你可能只想改变,以便在发生该错误状态时引发异常。通常,调试一旦遇到意外情况就失败的程序是最安全、最容易的。getMoreNewProducts()

如果发生这种情况是因为没有新产品,那么您应该只返回一个空集合,而不是 .在那之后,你的所有代码都应该可以正常工作,不需要 if/else 语句:它将返回 LessNewProducts 的空数组,这可能是正确的。null

但是,让我们假设您预计会不时发生某种情况,这将使您当时无法检索,但您希望系统以其他方式正常处理。你可以用它来指示该值不存在,但真的很难知道哪些变量可能是空的,哪些永远不应该是空的。使用可选类型来表示可能根本不返回任何内容可能更明智,因此您可以强制任何使用代码识别这种可能性,并在项目编译之前弄清楚如何处理它:newProductLinesnullgetMoreNewProducts()

public ActionResult Index(string search)
{
    Maybe<string[]> newProductLines = this.getMoreNewProducts();
    string[] newNews = this.getMoreNews();
    string[] newPromotions = this.getMorePromotions();
    Maybe<string[]> fewerProductLines = newProductLines.Select(this.getLessNewProducts);

免责声明:我是上面提到的类的作者。Maybe<>

以下是我建议的一些其他改进:

  1. 不要使用 ViewBag。相反,请创建一个强类型的 ViewModel,以便可以在编译时更频繁地捕获代码中的错误:

    var viewModel = new ReportModel {
        newProductLines = this.getMoreNewProducts(),
        newNews = this.getMoreNews(),
        ...
    };
    ...
    return View(viewModel);
    
  2. 了解如何使用 LINQ。它将简化许多非常复杂的代码。例如,而不是:

            string[] LessNewProducts = new string[arrayCount];
            for (int d = 0; d < arrayCount; d++)
            {
                LessNewProducts[d] = displayProductLines[d];
            }
            return LessNewProducts;
    

    ...你可以说:

            string[] LessNewProducts = displayProductLines.Take(arrayCount).ToArray();
    

    事实上,我认为你的整个方法可以用这个代替:getLessNewProducts()

    return newProductLines
        .Where(line => line.Length > 0)
        .Select(line => line.Substring(0, Math.Min(line.Length, 250)))
        .Take(5);