我正在维护一些代码,原作者已经不见了,所以我想在这里问一下我是否能满足自己的好奇心。
下面是一些使用产量的代码(匿名)。据我所知,它没有增加任何好处,只返回一个列表就足够了,也许更具可读性(至少对我而言)。只是想知道我是否遗漏了某些东西,因为这种模式在代码库中的几个地方重复出现。
public virtual IEnumerable<string> ValidProductTypes
{
get
{
yield return ProductTypes.Type1;
yield return ProductTypes.Type2;
yield return ProductTypes.Type3;
}
}
此属性用作某些类的参数,该类仅使用它来填充集合:
var productManager = new ProductManager(ValidProductTypes);
public ProductManager(IEnumerable<string> validProductTypes)
{
var myFilteredList = GetFilteredTypes(validProductTypes);
}
public ObservableCollection<ValidType> GetFilteredTypes(IEnumerable<string> validProductTypes)
{
var filteredList = validProductTypes
.Where(type => TypeIsValid); //TypeIsValid returns a ValidType
return new ObservableCollection<ValidType>(filteredList);
}
答案 0 :(得分:5)
我要说的是,返回IEnumerable<T>
并使用yield return
实现该功能是最简单的选项。
如果你看到某个方法返回IEnumerable<T>
,那么你只能做一件事:迭代它。对它进行任何更复杂的操作(比如使用LINQ)只是封装了特定的迭代方法。
如果一个方法返回一个数组或列表,你也可以改变它,你可能会开始想知道这是否是可接受的API使用。例如,如果您执行ValidProductTypes.Add("a new product")
会发生什么?
如果您只谈论实施,那么差异会变得更小。但调用者仍然能够将返回的数组或列表从IEnumerable<T>
强制转换为其具体类型并进行变异。任何人实际认为这是API的预期用途的可能性很小,但是yield return
,机会为零,因为它是不可能的。
考虑到我会说语法具有大致相同的复杂性和易于理解,我认为yield return
是一个合理的选择。虽然使用C#6.0表达式实体属性,但数组的语法可能占上风:
public virtual IEnumerable<string> ValidProductTypes =>
new[] { ProductTypes.Type1, ProductTypes.Type2, ProductTypes.Type3 };
上面的答案假设这不是性能关键代码,因此性能上相当小的差异无关紧要。如果这是性能关键代码,那么您应该测量哪个选项更好。你可能还想考虑去掉分配(可能是通过在一个字段中缓存数组,或类似的东西),这可能是主导因素。