使用方法内的“ToListAsync()”返回IEnumerable

时间:2016-04-06 16:53:07

标签: c# .net

目前我正在使用其他人的代码。这不是我第一次看到这样的事情:

public async MyMethod Task<IEnumerable<MyResult>> FindResults()
{
// some code here
var ret = await repository.BusinessObjects.ToListAsync()

return ret;

}

我的问题是:在MyMethod返回类型中使用 IEnumerable 是不是适得其反,因为结果已经枚举,最好是这样保留吗?使用列表不是更好吗?

(我想这也适用于非异步操作,但我决定以我在代码中看到的方式显示这个以防万一)

3 个答案:

答案 0 :(得分:5)

从技术上讲,以这种方式编写代码没有问题。在上面的特定代码示例中,如果您返回List<>实例但方法的返回类型为IEnumerable<>,则(技术上)无关紧要。没有性能损失,实际返回的类型仍为List<>

据说这不是好习惯。有一个设计指南,声明你应该构建你的方法,以便始终返回最具体的类型 AND 接受最通用/抽象类型(当然,在限制范围内,你不应该采取对象作为每种方法的参数)。

请参阅Vladimir Khorikov撰写的题为Return the most specific type, accept the most generic type的文章作为参考。之前也有人问过这个问题,请参阅Is it better to return the most specific or most general type from an action method?

所以这意味着以下2个签名将是良好的做法(使用您的示例),假设第一个签名a List<MyResult>是实际返回的类型,而在第二个示例中,无论做什么更新只需要迭代输入。

public async Task<List<MyResult>> FindResultsAsync();
public async Task UpdateAsync(IEnumerable<MyResult> itemsForUpdate);

答案 1 :(得分:0)

这取决于您的使用案例。 IEnumerable提供了更好的抽象,但它肯定会带来性能成本,具体取决于您的使用。

确实,您将迭代一次以创建列表异步并且(可能)再次作为可枚举的使用者进行迭代。

我个人(对于我的用例)使用您在非性能关键路径中显示的模式,例如初始化

答案 2 :(得分:0)

  

IEnumerable返回类型中使用MyMethod是否会适得其反,因为结果已经被枚举,并且保持这种方式会更好吗?使用List不是更好吗?

我不知道它会如何产生任何影响或为什么会出现问题。通常问题是当你返回一个惰性集合(比如一个EF查询)时,多次迭代导致多个数据库调用。

您正在返回List,因此多次迭代不是问题。如果您想要返回List,以便向来电者明确表示可以安全地多次迭代,但实际上并不是很好改变一切。

返回更多基类型有其他好处(例如,它允许您返回除List以外的不同集合类型),但是在您关注多个枚举的上下文中,是否返回类型为ListIEnumerable并不重要。