我目前在做的一个项目中,我们有许多静态表达式,当我们调用它们的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提供程序等...但我不太清楚为什么会起作用。
这里发生了什么?
usefulExpression.Invoke
这段代码不应该编译通过。你是否缺少了某些代码?Expression<Func<SomeDataType, bool>>
没有Invoke
成员。 - usr