我有3个具有以下属性的类:
OfferList类:
Guid Id
IEnumerable<Offer> Offers
提供课程:
Guid Id
Product Product
bool IsSealed
产品类别:
Guid Id
OfferList包含多个商品,商品包含1个商品。
如何过滤OfferList以仅包含未密封的商品?
OfferList offerList = this.GetOfferList(id).Offers.Where(o => !o.IsSealed));
这将返回一个类型为Offer的IEnumerable,而不是过滤OfferList。
答案 0 :(得分:12)
有趣 - 你在这里提出的问题有点令人困惑。
我想你问的是如何Offers
就地过滤。如果是这样的话:
IEnumerable<T>
是不可变的(你必须强制转换为具体的List<T>
或类似的才能获得可变性),Offers
是IEnumerable<T>
- 所以你不能指望Offers.Where(o => !o.IsSealed));
更改 Offers
属性 - 它会返回一个可枚举的枚举,在您枚举时过滤源。
相反,你会做
var offerList = this.GetOfferList(id)
offerList.Offers = offerList.Offers.Where(o => !o.IsSealed));
但请注意,对于共享Offers
实例的任何其他代码,这会隐藏原始OfferList
引用。在你开始枚举之前,它也不会实际进行任何过滤。但这通常更可取。如果您希望在那里完成,那么 - 在.ToArray()
的末尾使用.ToList()
或Where
来强制完成枚举。
更好的方法是在OfferList
类上拥有一个属性或方法,以便按需返回一个新的可枚举:
public IEnumerable<Offer> UnsealedOffers {
get {
return Offers.Where(o => !o.IsSealed);
}
}
这样你就不会破坏可枚举的主人。
请注意,此代码容易Offers
为空(NullReferenceException
)和,返回null枚举并不好(返回空的枚举) - 所以如果Offers
有可能为空 - 然后要么阻止它发生;或使用:
return (Offers ?? Enumerable.Empty<Offer>()).Where(o => !o.IsSealed);
答案 1 :(得分:1)
如果您要更新原始OfferList
实例,则可以将过滤后的序列分配到其Offers
字段:
OfferList offerList = this.GetOfferList(id);
offerList.Offers = offerList.Offers.Where(o => !o.IsSealed);
答案 2 :(得分:0)
您需要设置Offers
课程的OfferList
。您无法直接转换为OfferList
,因为它不是List
或未实现IEnumerable
。
OfferList list = new OfferList() { Offers = this.GetOfferList(id).Offers.Where(o => !o.IsSealed)) };
答案 3 :(得分:0)
您是否需要新的未密封优惠清单?
List<Offer> offers = this.GetOfferList(id).Offers
.Where(o => !o.IsSealed)
.ToList();