B\S备忘录23——Excalibur!!不对,是Expression!!

  上次是说明了一下下整个解决问题的过程是什么,总的来说还是从怀疑触发,验证怀疑的正确性,分而治之,这么看来跟平时写代码的习惯差不多嘛。

  写代码就是个滚雪球的效应,雪球越滚越大,逻辑越写越复杂,但是复杂的逻辑是通过简单的代码一点点演化来的,前期压着打,中期带线、单抓扩大优势,后期一波完美团战直接上高,GG。。。好像一不小心又写到了熟悉的地方了。

  好了,不说那么远了,先来说说上次留下的问题。

  Func<T,TResult> 和 Expression<Func<T,TResult>>。

  Func这个是一个委托,T表示委托的参数类型,TResult表示委托的返回值类型,这种用法直接就相当于生命了一个委托,并且要有返回值。

  Expression<Func<T,TResult>>是表达式,它与Func并不相同,它表示一种lambda表达式的树形结构,这个树形结构描述了lambda表达式的作用,而不是执行它们。它基本上是描述这个表达式的组成,变量,调用方式等数据(例如:这个lambda表达式是由一些常数和一些参数构成的)。当然这种把lambda表达式转换成匿名函数或是Expression表达式的行为,也是要消耗编译时间的。

  我们可以基于这种描述,来把它翻译成真正的方法来执行,或者做一些其他的事情,例如:Linq to SQL。微软提供了一种专门执行这种表达式的方法,Expression.Compile()。

  EF在实现Linq to SQL操作的时候是根据表达式树来创建SQL语句,我们的底层使用的返回值都是IQueryable<T>这种类型,我查到了EF里面关于这个类型的源码,发现它的构造函数使用的就是表达式类型的。

// Type: System.Linq.Queryable
// Assembly: System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
// Assembly location: C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.Core.dll
public static class Queryable
{
    public static IQueryable<TSource> Where<TSource>(
        this IQueryable<TSource> source, 
        Expression<Func<TSource, bool>> predicate)
    {
        return source.Provider.CreateQuery<TSource>(
            Expression.Call(
                null, 
                ((MethodInfo) MethodBase.GetCurrentMethod()).MakeGenericMethod(
                    new Type[] { typeof(TSource) }), 
                    new Expression[] { source.Expression, Expression.Quote(predicate) }));
    }
}
  而Func也有一种类型使用它,IEnumerable。

// Type: System.Linq.Enumerable
// Assembly: System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
// Assembly location: C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.Core.dll
public static class Enumerable
{
    public static IEnumerable<TSource> Where<TSource>(
        this IEnumerable<TSource> source, 
        Func<TSource, bool> predicate)
    {
        return (IEnumerable<TSource>) new Enumerable.WhereEnumerableIterator<TSource>(source, predicate);
    }
}
  所以啦,以后使用IQueryable就用Expression,IEnumberable就用Func。

  最后,所有的资料我都是从外文的网站上查出来的,希望渣翻译没有错。别误导大家。

  http://stackoverflow.com/questions/793571/why-would-you-use-expressionfunct-rather-than-funct#comment46321677_17034681

  http://ivanitskyi.blogspot.com/2013/06/linq-func-vs-expression.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 16
    评论
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值