提问人:ToiletPainter 提问时间:8/7/2015 最后编辑:Huang ChenToiletPainter 更新时间:8/7/2015 访问量:788
如何错误处理 NullReferenceException
How to Error Handle a NullReferenceException
问:
我的网站关闭了几天,因此我试图在 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 语句,以便整个事情不必崩溃?
答:
if (newProductLines == null)
应替换为 if (newProductLines != null),这样您就不必将 newProductLines 的代码作为 null 进行处理。基本上,在这种情况下,除非您使用 try catch 块管理异常,否则您将始终拥有 NullReferenceException。
两件事。
- 您的陈述有错误的条件。我不相信你想输入 if 为 null。您可以反转此条件以获得所需的结果()。
if (newProductLines == null)
newProductLines
if (newProductLines != null)
- 如果以后遇到需要捕获错误的另一种情况,则始终可以使用 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
}
真正要问自己的问题是:
为什么会为 null?
newProductLines
大概发现了一种情况,它认为返回一个值是合适的。getMoreNewProducts()
null
如果发生这种情况是因为系统有一个错误,使你的页面变得毫无意义,那么你可能只想改变,以便在发生该错误状态时引发异常。通常,调试一旦遇到意外情况就失败的程序是最安全、最容易的。getMoreNewProducts()
如果发生这种情况是因为没有新产品,那么您应该只返回一个空集合,而不是 .在那之后,你的所有代码都应该可以正常工作,不需要 if/else 语句:它将返回 LessNewProducts 的空数组,这可能是正确的。null
但是,让我们假设您预计会不时发生某种情况,这将使您当时无法检索,但您希望系统以其他方式正常处理。你可以用它来指示该值不存在,但真的很难知道哪些变量可能是空的,哪些永远不应该是空的。使用可选类型来表示可能根本不返回任何内容可能更明智,因此您可以强制任何使用代码识别这种可能性,并在项目编译之前弄清楚如何处理它:newProductLines
null
getMoreNewProducts()
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<>
以下是我建议的一些其他改进:
不要使用 ViewBag。相反,请创建一个强类型的 ViewModel,以便可以在编译时更频繁地捕获代码中的错误:
var viewModel = new ReportModel { newProductLines = this.getMoreNewProducts(), newNews = this.getMoreNews(), ... }; ... return View(viewModel);
了解如何使用 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);
评论