【问题标题】:C# LINQ lambda expression with Contains as a method parameter包含作为方法参数的 C# LINQ lambda 表达式
【发布时间】:2020-07-30 02:12:54
【问题描述】:

我正在编写一个获取 lambda 表达式作为参数的方法,用于过滤 IList<SomeModel> _collection

public void DoSomething(SomeModel model)
{
   FilterCollectionUsingPredicate(x => x.Name.Equals(model.Name));
}

private void FilterCollectionUsingPredicate(Func<SomeModel, bool> predicate)
{
   _collection = _collection.Where(predicate).ToList();
}

predicate 参数是一个简单的表达式时,它工作得很好,比如x =&gt; x.Name.Equals(model.Name)。 但是,当它必须使用一些其他(本地)集合和 Contains 子句时,它会变得很棘手。

public void DoSomething(SomeModel model)
{
   IEnumerable<string> someOtherCollection = model.SomeOtherCollection;
   FilterCollectionUsingPredicate(x => someOtherCollection.Contains(x.Phone));
}

private void FilterCollectionUsingPredicate(Func<SomeModel, bool> predicate)
{
   _collection = _collection.Where(predicate).ToList();
}

当然,FilterCollectionUsingPredicate 方法看不到someOtherCollection,因此会引发错误。 有人能解释一下如何正确定义和使用这个函数来处理这种情况吗?

【问题讨论】:

  • 抛出什么错误?仅供参考 someOtherCollection 将作为粘贴的 lambda 的一部分被捕获。
  • 我认为predicate 必须是Expression 而不是Fun
  • 您将不得不添加更多细节,因为我试图重现这一点并且它工作得很好。至少我们需要知道错误。
  • @Sajid 我对此表示怀疑,因为在分配给_collection 时使用ToList 表示我们没有处理IQueryable。但是_collection 可能是一个IEnumerable,OP 首先分配一个IQueryable。这只是 OP 提供更多细节的另一个原因。
  • @juharr:你是对的,问题中的解决方案,它工作正常。没有错误。

标签: c# linq lambda contains func


【解决方案1】:

尝试创建一个通用扩展,Expression 应该跟踪表达式中的所有其他数据。尝试将谓词创建为表达式

private void FilterCollectionUsingPredicate(Expression<Func<SomeModel, bool>> predicate)
{
   _collection = _collection.Where(predicate).ToList();
}

它应该可以工作。

【讨论】:

  • 这可能是答案,但问题中没有任何内容暗示它是。
  • Func 不会跟踪所有其他外部项目,这就是您出错的原因。表达式跟踪表达式中原始项目的路径或路径
  • @Alen.Toma 这完全不正确。捕获 Func&lt;&gt; 类型的 lambda 中的所有局部变量。
  • 如果提供者要像 EF 那样翻译代码以翻译成 SQL,您只需要它是一个表达式。如果这是使用 Linq-to-Objects,则 lambda 将捕获在其闭包内使用的任何变量。
猜你喜欢
  • 1970-01-01
  • 2012-12-27
  • 1970-01-01
  • 2018-09-29
  • 1970-01-01
  • 1970-01-01
  • 2016-10-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多