为什么不在这里使用表达式,为什么不使用Func?

时间:2018-01-04 14:58:19

标签: c# expression

假设我有以下课程......

public class Person {
  public string Name { get; set; }
  public string Nickname { get; set; }
}

...我希望能够(单独)检查NameNickname属性是否以“a”开头。

我可以写两个像这样的方法......

public bool NameStartsWithA(Person p) {
  return p.Name.ToLower().StartsWith("a");
}

public bool NicknameStartsWithA(Person p) {
  return p.Nickname.ToLower().StartsWith("a");
}

然而,这违反了DRY(在这个人为简单的例子中不是一个大问题,但在现实世界中可能很重要)。

搜索周围,似乎答案是做以下事情......

public bool StartsWithA(Person p, Expression<Func<Person, string>> f) {
  return f.Compile()(p).ToLower().StartsWith("a");
}

...然后可以按如下方式调用......

bool b = StartsWithA(person, p => p.Name);

这很好用,但我想知道Expression的意思。如果我删除它,并使方法看起来像这样......

public bool StartsWithA(Person p, Func<Person, string> f) {
  return f(p).ToLower().StartsWith("a");
}

......它似乎同样有效。

Expression有什么意义吗?看看“Why would you use Expression> rather than Func?”似乎Expression在这种情况下并没有给我带来任何好处(除了执行速度的微小改进,根据场景可能会或可能不会很重要)因为我正在做的就是执行它,而不是修改它。

1 个答案:

答案 0 :(得分:3)

  

在这种情况下,表达似乎并没有给我任何好处

是的,你是对的。

当我们想要使用传递给lambda表达式的函数体时,通常使用expression,在正常情况下我们只需要在内存中对某些数据执行一个方法已经在记忆中Func应该不错。

在您在问题中提到的帖子中,您可以看到答案,因为在 Linq To Sql 实体框架中实现某些数据提取逻辑时,它可能非常有用。他们使用Expression检查传入的信息,然后将其转换为SQL语句。

来自Mehrdad's answer引用:

  

从概念上讲,Expression<Func<T>>Func<T>完全不同。 Func<T>表示委托,它几乎是指向方法的指针,Expression<Func<T>>表示lambda表达式的树数据结构。这个树结构描述了lambda表达式的作用而不是实际的东西。

所以很清楚这两者有多大不同,这应该让你有足够的想法何时使用哪一个。

希望它有帮助!