我的客户端代码在四种不同的方法中几乎相同(不同之处在于调用的特定Web API RESTful方法和相应的操作通用列表)。
在四种情况中的三种情况下,我可以像这样突破while循环(参见How can I safely loop until there is nothing more to do without using a "placeholder" 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存储库代码就像以前一样/与其他代码一样。
所以问题:哪个是首选方法(没有双关语意)?
答案 0 :(得分:5)
您绝对应该更改最后一个方法以匹配之前的方法:
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;
}
答案 1 :(得分:2)
你应该返回一个空集合。
所有具有基于IEnumerable
的返回类型的Linq方法(我知道)返回空集合而不是null
。从方法中返回null
会阻止您链接方法调用,因为您现在需要检查null
以避免NullReferenceExcpetion
(正如您所发现的那样)。