假设我的对象处于完美的工作状态(即TDD让我觉得它们有效).
我有一个我这样创建的列表(正确缩进除外):
var result = from v in vendors from p in v.Products orderby p.Name select p;
这有效 - 我从所有供应商处获得所有产品.
现在我有一个条件列表,由用户在运行时构建.让我们应用它们:
foreach (Attribute a in requiredAttributes) { result = result.Where(p => p.Attributes.Contains(a)); }
这可能是原始的,但我认为它有用.但是,在完成此foreach循环之后,当您枚举"result"时,它将包含其Attributes属性(也是集合)中具有requiredAttributes集合的LAST属性的所有产品.
对我来说,这种气味就像"a"被覆盖在某个地方,每次旅行通过循环,只有最后一个适用.
如果没有以某种方式将扩展方法写入IEnumerable,称为ContainsAll(IEnumerable)或其他类似的东西,我怎么能实现我想要的,这基本上是一个逻辑AND,只给我那些具有所有必需属性的产品?
(为清晰起见而编辑.)
问题是foreach循环,以及每次捕获然后更改"a"变量的事实.这是一个有效的修改,通过为循环的每次迭代有效地引入一个"新"变量,并捕获该新变量.
foreach (Attribute a in requiredAttributes) { Attribute copy = a; result = result.Where(p => p.Attributes.Contains(copy)); }
如果您可以使用它,Omer的解决方案更简洁,但如果您的真实代码实际上更复杂,这可能会有所帮助:)
编辑:关于这个闭包文章的问题还有更多- 向下滚动到"比较捕获策略:复杂性与功率".
var result = from v in vendors from p in v.Products where requiredAttributes.All(a => p.Attributes.Contains(a)) orderby p.Name select p;
HTH.
我没有编码,但改变了
foreach (Attribute a in requiredAttributes){ result = result.Where(p => p.Attributes.Contains(a)); }
至
foreach (Attribute a in requiredAttributes){ Attribute b = a; result = result.Where(p => p.Attributes.Contains(b)); }
我想也应该修理它.