C# 过滤IEnumerable
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13700635/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Filter IEnumerable
提问by niklr
I have 3 classes with the following properties:
我有 3 个具有以下属性的类:
OfferList class:
OfferList 类:
Guid Id
IEnumerable<Offer> Offers
Offer class:
优惠等级:
Guid Id
Product Product
bool IsSealed
Product class:
产品类别:
Guid Id
An OfferList contains multiple Offers and an Offer has exact 1 Product.
一个OfferList 包含多个Offer,而一个Offer 正好有1 个产品。
How can I filter the OfferList to contain only Offers which are not sealed?
如何过滤 OfferList 以仅包含未密封的 Offer?
OfferList offerList = this.GetOfferList(id).Offers.Where(o => !o.IsSealed));
This returns an IEnumerable of type Offer instead of filtering the OfferList.
这将返回一个 Offer 类型的 IEnumerable,而不是过滤 OfferList。
采纳答案by Andras Zoltan
Interesting - it is a little confusing what you're asking here.
有趣 - 你在这里问的有点令人困惑。
I thinkyou're asking how to have Offersfiltered in-place. If so:
我想你是在问如何Offers就地过滤。如果是这样的话:
IEnumerable<T>is immutable (you have to cast to a concrete List<T>or similar to get mutability), and Offersis an IEnumerable<T>- so you can't expect Offers.Where(o => !o.IsSealed));to changethe Offersproperty - it returns an enumerable that filters the source as you enumerate it.
IEnumerable<T>是不可变的(你必须要转换成具体的List<T>或类似的获得可变性),并且Offers是IEnumerable<T>-所以你不能指望Offers.Where(o => !o.IsSealed));到改变的Offers属性-它返回你枚举它可以过滤源可枚举。
Instead you'd do
相反,你会做
var offerList = this.GetOfferList(id)
offerList.Offers = offerList.Offers.Where(o => !o.IsSealed));
Note, however, that this hides the original Offersreference for any other code sharing that OfferListinstance. It also doesn't actually do any filtering until you start enumerating, either. But that's often preferable. If you want it done there and then - use .ToArray()or .ToList()at the end of the Whereto force the enumeration to be done.
但是请注意,这隐藏了Offers共享该OfferList实例的任何其他代码的原始引用。在您开始枚举之前,它实际上也不会进行任何过滤。但这通常是可取的。如果您希望在那里完成,然后 - 使用.ToArray()或.ToList()在结束时Where强制完成枚举。
A better approach would be to have a property or method on the OfferListclass that returns a new enumerable on-demand:
更好的方法是在OfferList类上使用一个属性或方法来按需返回新的可枚举:
public IEnumerable<Offer> UnsealedOffers {
get {
return Offers.Where(o => !o.IsSealed);
}
}
That way you're not destroying the master enumerable.
这样你就不会破坏主枚举。
Note that this code is susceptible to Offersbeing null (a NullReferenceException) andthat it's not great to return null enumerables (return empty ones instead) - so if there is a chance that Offerscan be null - then either stop that from happening; or use:
请注意,此代码容易为Offersnull (a NullReferenceException)并且返回 null 可枚举项(而是返回空的)并不是很好 - 所以如果有Offers可能为 null - 那么要么阻止这种情况发生;或使用:
return (Offers ?? Enumerable.Empty<Offer>()).Where(o => !o.IsSealed);
回答by LukeHennerley
You need to set the Offersof your OfferListclass. You can't directly cast to the OfferListbecause it isn't a Listor doesn't implement IEnumerable.
你需要设置Offers你的OfferList班级。您不能直接强制转换为 ,OfferList因为它不是 aList或没有实现IEnumerable。
OfferList list = new OfferList() { Offers = this.GetOfferList(id).Offers.Where(o => !o.IsSealed)) };
OfferList list = new OfferList() { Offers = this.GetOfferList(id).Offers.Where(o => !o.IsSealed)) };
回答by Douglas
If you mean that you want to update your original OfferListinstance, you could just assign the filtered sequence to its Offersfield:
如果您的意思是要更新原始OfferList实例,则只需将过滤后的序列分配给其Offers字段:
OfferList offerList = this.GetOfferList(id);
offerList.Offers = offerList.Offers.Where(o => !o.IsSealed);
回答by Tim Schmelter
Do you need a new list of un-sealed offers?
您需要一份新的未密封报价清单吗?
List<Offer> offers = this.GetOfferList(id).Offers
.Where(o => !o.IsSealed)
.ToList();

