在我目前正在处理的一个项目中,我们有许多静态表达式,当我们在它们上调用 Invoke 方法并将我们的 lambda 表达式的参数传递给时,我们必须将它们带入局部范围。
今天,我们声明了一个静态方法,其参数正是查询所期望的类型。因此,我和我的同事正在四处寻找是否可以在查询的 Select 语句中使用此方法来执行项目,而不是在整个对象上调用它,而不是将其带入本地范围。
它奏效了!但我们不明白为什么。
想象一下这样的代码
// old way
public static class ManyExpressions {
public static Expression<Func<SomeDataType, bool> UsefulExpression {
get {
// TODO implement more believable lies and logic here
return (sdt) => sdt.someCondition == true && false || true;
}
}
}
public class ARealController : BaseController {
/* many declarations of important things */
public ARealClass( /* many ninjected in things */) {
/* many assignments */
}
public JsonNet<ImportantDataResult> getSomeInfo(/* many useful parameter */) {
var usefulExpression = ManyExpressions.UsefulExpression;
// the db context is all taken care of in BaseController
var result = db.SomeDataType
.Where(sdt => usefulExpression.Invoke(sdt))
.Select(sdt => new { /* grab important things*/ })
.ToList();
return JsonNet(result);
}
}
然后你就可以做到了!
// new way
public class SomeModelClass {
/* many properties, no constructor, and very few useful methods */
// TODO come up with better fake names
public static SomeModelClass FromDbEntity(DbEntity dbEntity) {
return new SomeModelClass { /* init all properties here*/ };
}
}
public class ARealController : BaseController {
/* many declarations of important things */
public ARealClass( /* many ninjected in things */) {
/* many assignments */
}
public JsonNet<SomeModelClass> getSomeInfo(/* many useful parameter */) {
// the db context is all taken care of in BaseController
var result = db.SomeDataType
.Select(SomeModelClass.FromDbEntity) // TODO; explain this magic
.ToList();
return JsonNet(result);
}
}
因此,当 ReSharper 提示我执行此操作时(这并不常见,因为通常不满足与委托所期望的类型匹配的条件),它说转换为方法组。我有点模糊地理解方法组是一组方法,C# 编译器可以负责将方法组转换为 LINQ 提供程序的显式类型和适当的重载等等......但我对为什么这完全有效。
这里发生了什么?