确定将内部List <t>作为IEnumerable <t>或ICollection <t>返回?</t> </t> </t>

时间:2012-04-16 22:25:19

标签: c# collections return return-type

  

可能重复:
  Collection<T> versus List<T> what should you use on your interfaces?

考虑这个方法 - 返回的变量myVarList<T>,但方法MyMethod()的返回类型是IEnumerable<T>

public IEnumerable<T> MyMethod(string stuff)
{
     var myVar = new List<T>();
     //do stuff

     return myVar;
}

基本上,我想知道的是,如果将myVar作为其他类型返回就可以了。

具体来说,就我的情况而言,'do stuff'会通过DataRow并将DataRow中的项目分配给对象列表。我也有其他地方ICollectionIList返回类型的类似情况。

我想要返回IEnumerableICollection的原因是我不会返回超过需要的内容。但与此同时,如果需要,调用者可以将返回值转换为List

然而,我的return语句返回List而不是方法的返回类型似乎很奇怪。这是正常做法吗?这样做有什么不对吗?

澄清(回应重复评论):

只是为了澄清一下,我很好奇的是,如果我的正文中的return语句返回List<T>是可以的,但方法标题的返回类型为IEnumerable,或者可能是ICollectionCollection等......某些不同而非身体返回陈述。

4 个答案:

答案 0 :(得分:6)

它不仅没有任何问题,而且它实际上是一种很好的做法:只暴露严格必要的东西。这样,调用者不能依赖于该方法将返回List<T>这一事实,因此如果由于某种原因您需要更改实现以返回其他内容,则不会违反合同。但是,如果调用代码(错误地)对方法实际返回的内容做出了假设,那么调用代码可能会中断。

答案 1 :(得分:3)

返回IEnumerable<T>类型的原因是调用者无法修改列表(不将其强制转换回列表)。如果您注意到所有(大多数?)扩展方法采用IEnumerable<T>参数,那么您就知道扩展方法不会修改您的列表。

其次,List<T>继承自IEnumerable<T>

修改 正如Thomas在评论中解释的那样,IEnumerable<T>可以被强制转换为List<T>并由调用者修改。如果您的主要目标是将其设为只读,则可以将列表作为myVar.AsReadOnly()返回。但是类型是ReadOnlyCollection<T>

答案 2 :(得分:2)

它没有任何问题。

实际上返回具体类是满足“返回接口”要求的唯一方法。

如果您让特定类的知识潜入调用代码(List<T> r = (List<T>)MyMethod("ff")),则可能存在缺陷。但是,如果你将结果视为界面(如你所愿),那就没关系。

答案 3 :(得分:1)

我认为这不是最佳的,因为它允许调用者强制转换为List<T>,这依赖于实现细节。我会添加某种掩码,例如Select(x=>x)

动态类型的调用方可能甚至没有注意到您将列表转换为IEnumerable<T>。对他而言,这只是List<T>

将内部永久List<T>作为IEnumerable<T>返回将是非常错误的,因为它允许调用者改变您的类的内部状态。但是,由于您在每次调用时返回List<T>的新实例,而在其他任何地方都没有使用,所以此参数不适用于您的示例。