我的客户端代码在四种不同的方法中几乎是相同的(不同之处在于调用的特定Web API RESTful方法和相应的操作泛型列表)。
在四种情况中的三种情况下,我可以突破while循环(请参阅如果不使用"占位符"while conditon,我如何安全地循环直到没有其他事情可做?)
if (arr.Count <= 0) break;
但在一种情况下,一旦RESTful方法不再返回数据,就会导致NRE。在这种方法中,我必须使用:
if (null == arr) break;
我现在知道为什么了,所以这个:
更新
不同行为的原因是存储库代码不同。因此,我将问题从"为什么检查JArray.Count在大多数情况下有效,但在一种特定情况下会导致NRE?"
以下是检查数组计数的三种方法:
public IEnumerable<Subdepartment> Get(int ID, int CountToFetch)
{
return subdepartments.Where(i => i.Id > ID).Take(CountToFetch);
}
这是RedemptionRepository:中包含的"备用版本"
public IEnumerable<Redemption> Get(int ID, int CountToFetch)
{
IEnumerable<Redemption> redempts = null;
if (redemptions.Where(i => i.Id > ID).Take(CountToFetch).Count() > 0)
{
redempts = redemptions.Where(i => i.Id > ID).Take(CountToFetch);
}
return redempts;
}
因此,为了与所有四种方法保持一致,我可以使所有其他Repository方法与上述方法类似(当找不到数据时返回null),并将客户端中的测试条件更改为无效,或者我可以将Redemption存储库代码恢复为以前的/与其他方法类似。
那么问题来了:哪一种是首选方法(并非双关语)?
您肯定应该更改最后一个方法以匹配前面的方法:
public IEnumerable<Redemption> Get(int ID, int CountToFetch)
{
return redemptions.Where(i => i.Id > ID).Take(CountToFetch);
}
NullReferenceException
并不是唯一的原因。因为LINQ是惰性的并且执行是延迟的,所以另一种方法执行查询两次!一次得到Count()
,第二次得到实际的结果集合。如果您真的想返回null
而不是空集合,则应使用以下内容:
public IEnumerable<Redemption> Get(int ID, int CountToFetch)
{
var redempts = redemptions.Where(i => i.Id > ID).Take(CountToFetch).ToList();
if (redemptions.Any())
{
return redempts;
}
return null;
}
您应该返回一个空集合。
所有具有基于IEnumerable
的返回类型的Linq方法(我知道)都返回空集合,而不是null
。从方法返回null
可以防止链接方法调用,因为现在需要检查null
以避免NullReferenceExcpetion
(正如您所发现的)。