7

我有 3 个具有以下属性的类:

优惠清单类:

Guid Id
IEnumerable<Offer> Offers

优惠等级:

Guid Id
Product Product
bool IsSealed

产品类别:

Guid Id

一个 OfferList 包含多个 Offer,一个 Offer 有确切的 1 个产品。

如何过滤 OfferList 以仅包含未密封的 Offer?

OfferList offerList = this.GetOfferList(id).Offers.Where(o => !o.IsSealed));

这将返回类型为 Offer 的 IEnumerable,而不是过滤 OfferList。

4

4 回答 4

15

有趣 - 你在这里问的内容有点令人困惑。

你是在问如何Offers就地过滤。如果是这样的话:

IEnumerable<T>是不可变的(您必须转换为具体的List<T>类似的以获得可变性),并且OffersIEnumerable<T>- 所以您不能期望Offers.Where(o => !o.IsSealed));更改属性 - 它返回一个可枚举的,在您枚举它时过滤源。Offers

相反,你会做

var offerList = this.GetOfferList(id)
offerList.Offers = offerList.Offers.Where(o => !o.IsSealed));

但是请注意,这隐藏了共享该实例Offers的任何其他代码的原始引用。OfferList在您开始枚举之前,它实际上也不会进行任何过滤。但这通常更可取。如果您希望它在那里完成,然后 - 使用.ToArray()or.ToList()在结尾处Where强制完成枚举。

更好的方法是在OfferList类上有一个属性或方法,它可以按需返回一个新的可枚举:

public IEnumerable<Offer> UnsealedOffers {
  get {
    return Offers.Where(o => !o.IsSealed);
  }
}

这样你就不会破坏主可枚举。

请注意,此代码容易为Offersnull (a NullReferenceException) ,并且返回 null 可枚举(而不是返回空的枚举)并不是很好 - 所以如果有Offers可能为 null - 那么要么阻止这种情况发生;或使用:

return (Offers ?? Enumerable.Empty<Offer>()).Where(o => !o.IsSealed);
于 2012-12-04T10:25:27.583 回答
1

如果您的意思是要更新原始OfferList实例,则可以将过滤后的序列分配给其Offers字段:

OfferList offerList = this.GetOfferList(id);
offerList.Offers = offerList.Offers.Where(o => !o.IsSealed);
于 2012-12-04T10:23:18.987 回答
1

您需要一份新的未密封报价清单吗?

List<Offer> offers = this.GetOfferList(id).Offers
                         .Where(o => !o.IsSealed)
                         .ToList();
于 2012-12-04T10:28:32.970 回答
0

你需要设置Offers你的OfferList班级。您不能直接转换为 ,OfferList因为它不是 aList或未实现IEnumerable

OfferList list = new OfferList() { Offers = this.GetOfferList(id).Offers.Where(o => !o.IsSealed)) };

于 2012-12-04T10:22:37.690 回答