yield关键字是c#中一直困扰我的关键字之一,我从来都不确定自己是否正确地使用了它。
在以下两段代码中,哪一段是首选的,为什么?
版本1:使用收益率
public static IEnumerable<Product> GetAllProducts()
{
using (AdventureWorksEntities db = new AdventureWorksEntities())
{
var products = from product in db.Product
select product;
foreach (Product product in products)
{
yield return product;
}
}
}
版本2:返回列表
public static IEnumerable<Product> GetAllProducts()
{
using (AdventureWorksEntities db = new AdventureWorksEntities())
{
var products = from product in db.Product
select product;
return products.ToList<Product>();
}
}
这有点离题了,但由于这个问题被标记为最佳实践,我将继续发表我的意见。对于这种类型的东西,我非常喜欢把它变成一个属性:
public static IEnumerable<Product> AllProducts
{
get {
using (AdventureWorksEntities db = new AdventureWorksEntities()) {
var products = from product in db.Product
select product;
return products;
}
}
}
当然,它更像一个样板,但使用它的代码将看起来更干净:
prices = Whatever.AllProducts.Select (product => product.price);
vs
prices = Whatever.GetAllProducts().Select (product => product.price);
注意:我不会对任何可能需要一段时间才能完成工作的方法这样做。
以下是Chris Sells在《c#程序设计语言》中讲述的语句;
I sometimes forget that yield return is not the same as return , in
that the code after a yield return can be executed. For example, the
code after the first return here can never be executed:
int F() {
return 1;
return 2; // Can never be executed
}
In contrast, the code after the first yield return here can be
executed:
IEnumerable<int> F() {
yield return 1;
yield return 2; // Can be executed
}
This often bites me in an if statement:
IEnumerable<int> F() {
if(...) {
yield return 1; // I mean this to be the only thing returned
}
yield return 2; // Oops!
}
In these cases, remembering that yield return is not “final” like
return is helpful.