当我有一个返回对象集合的方法时,如果对象计数为零,我应该返回什么? null
或只是空List<T>
?什么是好的做法?
public List<string> GetPupilsByClass(string className)
{
....
}
答案 0 :(得分:15)
我肯定会返回一个空列表,因此仍然可以在对象上调用方法而无需进行空检查。返回空列表并且根本不返回任何内容之间存在差异,因此调用代码可能不会期望接收空引用(除非发生异常或其他内容)。
答案 1 :(得分:3)
这取决于许多因素,但空列表将是更多典型的返回值,否则调用者必须知道执行null
检查。我返回null
的主要时间是它是否是这种风格的方法:
bool Try*(args, out result)
来电者希望(在接收false
时)甚至看的值为result
。
如果你碰巧正在返回数组,那就有一个很好的作弊 - 你可以在一个静态字段中存储一个零长度的类型数组。但最终一个空列表不会是一个巨大的分配开销,所以只是发送它。
答案 2 :(得分:3)
我希望作为来电者使用空列表。 Null会向我表明“概念列表”未定义,如数据库中的null。
此外,通过始终返回空集合而不是null,像这样的客户端永远不会失败:
foreach(var element in obj.Method()) ...
答案 3 :(得分:2)
根据MS的说法,你永远不应该从字段或属性中返回一个空字符串或数组,我认为这可以扩展到方法(可能是某些我还没找到的地方)。
返回空数组时:
String和Array属性永远不应返回空引用。在这种情况下,Null很难理解。
一般规则是null,空字符串(“”)和空(0项)数组应该以相同的方式处理。返回一个空数组而不是空引用。
答案 4 :(得分:1)
这个方法是ifc方法吗?这意味着外部物体不受你控制? 如果回答是,那么我将返回一个空集合,因为调用者不期待异常。
如果此方法是内部的并且您将是唯一的用户,我将返回null以保存为空集合分配的浪费内存以及一旦停止使用它就会触及GC性能。
答案 5 :(得分:1)
更好的做法是返回IEnumerable<string>
。在方法中使用yield return
和yield break
来构建您的收藏集。以这种方式,您推迟创建数组。查看here以获取更多信息。您会发现IEnumerable
具有可以在扩展方法和linq查询中链接的好处:
var results = from x in GetPupilsByClass(className) where x.StartsWith("A");
如果您绝对必须返回完整列表(由于yield
的懒惰性质),那么我建议您将方法签名更改为以下内容:
public bool TryGetPupilsByClass(string className, out ICollection<string> pupils)
这种技术有三个优点。
ICollection<string>
是强类型的,不会泄露您正在使用的存储机制。应谨慎使用返回的具体课程。替代方案是IList<string>
,ReadOnlyCollection<string>
和IEnumerable<string>
之类的内容,但您选择的内容肯定会让您对用户可以做什么和不能做什么的意图更加清晰。答案 6 :(得分:1)
始终返回空列表。并且您将避免最常发生的异常 - NullReferenceException
。
答案 7 :(得分:0)
这取决于您的代码使用的上下文。在大多数情况下,我会返回一个零对象列表,我认为这也是最好的 - 它与您的正常结果更加一致。
答案 8 :(得分:0)
我通常遵循R.Martin的“清洁代码”指南。建议返回一个空列表:
公共列表GetPupilsByClass(string className) { .... }
我这样做的原因如下: