【问题标题】:Is it necessary to use () with the Contains method? [duplicate]有必要在 Contains 方法中使用 () 吗? [复制]
【发布时间】:2020-05-22 06:26:08
【问题描述】:

我的代码如下所示:

string target = ListOfTabs.FirstOrDefault(e.Target.Location.OriginalString.Contains);

我没有编写代码,我正在尝试了解它的作用。我看到有一个方法叫Contains(),但是这里不明白为什么Contains后面没有()。这是不同的事情吗?有人能解释一下这段代码在做什么吗?

【问题讨论】:

  • Contains 是一个函数,Contains(..) 是对该函数的调用。

标签: c# list linq enumerable


【解决方案1】:

FirstOrDefault 基本上将函数作为参数。写作

ListOfTabs.FirstOrDefault(e.Target.Location.OriginalString.Contains);

实际上和写作一样

ListOfTabs.FirstOrDefault(x => e.Target.Location.OriginalString.Contains(x));

Containsx => Contains(x) 都是函数,所以它可以工作!

【讨论】:

  • 此外,即使第二行代码更具可读性和易于理解,它也会在创建新对象时产生成本。
  • @Orace Not true
  • @canton7 您提供的链接显示 lambda 版本的编译器不必要地定义了一个新的 [CompilerGenerated] 方法 <M>b__1_0(String) - 而这 不会 导致任何 GC 堆分配(并且 JIT 可能会内联函数)令人失望的是 C# 编译器不会自动内联琐碎的 lambda。
  • @Orace 这个问题比较了创建委托与不创建委托,委托正在捕获。上述问题中的代表都没有捕获
  • @Dai 是的,我发现这很奇怪——我已经asked about that on gitter。我假设这将是一个毫无意义的优化。编译器不缓存生成的委托也是不寻常的:通常它会
【解决方案2】:

您不需要它,因为FirstOrDefault 在参数中带有Func。由于Contains 匹配所要求的类型,因此您可以像将任何参数传递给任何其他函数一样传递Contains

FirstOrDefault 的签名是:

public static TSource FirstOrDefault<TSource> (this System.Collections.Generic.IEnumerable<TSource> source, Func<TSource,bool> predicate);

你习惯写:

var target = ListOfTabs.FirstOrDefault(x => e.Target.Location.OriginalString.Contains(x));

与此相同

Func<string, bool> predicate = x => e.Target.Location.OriginalString.Contains(x);
var target = ListOfTabs.FirstOrDefault(predicate);

与此相同

Func<string, bool> predicate = e.Target.Location.OriginalString.Contains;
var target = ListOfTabs.FirstOrDefault(predicate);

此时可以直接传Contains

var target = ListOfTabs.FirstOrDefault(e.Target.Location.OriginalString.Contains);

【讨论】:

    【解决方案3】:

    FirstOrDefault 接受 Func&lt;TSource, bool&gt; 作为它的参数。

    通常这将是一个 lambda 表达式,但由于 string.Contains 可以转换为 Func&lt;string, bool&gt;,它可以直接传递给方法(假设 ListOfTabsIEnumerable&lt;string&gt;)。

    FirstOrDefault的实现中,()语法将用于实际执行string.Contains

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-11-17
      • 2013-03-14
      • 2019-05-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-21
      相关资源
      最近更新 更多