5

可能重复:
Collection<T> 与 List<T> 您应该在界面上使用什么?

考虑这个方法——返回的变量myVar是 a List<T>,但方法的返回类型MyMethod()是 an IEnumerable<T>

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

     return myVar;
}

本质上,我想知道的是,myVar作为不同类型返回是否可以。

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

我想返回IEnumerable或返回的原因ICollection是我返回的数量不会超过需要。但同时,这允许调用者在需要时将返回的值转换为 a List

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

澄清(回应欺骗评论):

澄清一下,我很好奇的是,如果我在 body 中的 return 语句返回 a 是否可以List<T>,但方法头的返回类型为IEnumerable,或者可能ICollectionCollection等等...与 body不同的东西返回声明。

4

4 回答 4

6

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

于 2012-04-16T22:32:00.877 回答
3

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

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

编辑: 正如托马斯在评论中解释的那样,IEnumerable<T>可以将其转换回 aList<T>并由调用者修改。如果您的主要目标是使其成为只读,则可以将列表返回为myVar.AsReadOnly(). 但是类型是ReadOnlyCollection<T>.

于 2012-04-16T22:28:39.097 回答
2

没有什么问题。

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

如果你让特定类的知识潜入调用代码(List<T> r = (List<T>)MyMethod("ff")),可能会有缺点。但是,如果您将结果视为接口(如您所愿),那就可以了。

于 2012-04-16T22:28:06.920 回答
1

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

动态类型的调用者甚至可能不会注意到您将列表转换为IEnumerable<T>. 对他来说,简直了List<T>

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

于 2012-04-16T22:37:22.827 回答