解析C#的扩展方法

2019-12-30 15:04:17于海丽

以上分别介绍了Range()和Where()两个方法,该类中还主要包含select()、orderby()等等方法。

  2.Queryable类中的常用方法:

 (1).IQueryable接口:


 /// <summary>
 /// 提供对未指定数据类型的特定数据源的查询进行计算的功能。
 /// </summary>
 /// <filterpriority>2</filterpriority>
 public interface IQueryable : IEnumerable
 {
 /// <summary>
 /// 获取与 <see cref="T:System.Linq.IQueryable"/> 的实例关联的表达式目录树。
 /// </summary>
 /// 
 /// <returns>
 /// 与 <see cref="T:System.Linq.IQueryable"/> 的此实例关联的 <see cref="T:System.Linq.Expressions.Expression"/>。
 /// </returns>
 Expression Expression { get; }
 /// <summary>
 /// 获取在执行与 <see cref="T:System.Linq.IQueryable"/> 的此实例关联的表达式目录树时返回的元素的类型。
 /// </summary>
 /// 
 /// <returns>
 /// 一个 <see cref="T:System.Type"/>,表示在执行与之关联的表达式目录树时返回的元素的类型。
 /// </returns>
 Type ElementType { get; }
 /// <summary>
 /// 获取与此数据源关联的查询提供程序。
 /// </summary>
 /// 
 /// <returns>
 /// 与此数据源关联的 <see cref="T:System.Linq.IQueryProvider"/>。
 /// </returns>
 IQueryProvider Provider { get; }
 }

(2).Where():


 public static IQueryable<TSource> Where<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, bool>> predicate) { 
   if (source == null)
    throw Error.ArgumentNull("source"); 
   if (predicate == null)
    throw Error.ArgumentNull("predicate");
   return source.Provider.CreateQuery<TSource>(
    Expression.Call( 
     null,
     ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(typeof(TSource)), 
     new Expression[] { source.Expression, Expression.Quote(predicate) } 
     ));
  }

 (3).Select():


  public static IQueryable<TResult> Select<TSource,TResult>(this IQueryable<TSource> source, Expression<Func<TSource, TResult>> selector) {
   if (source == null)
    throw Error.ArgumentNull("source");
   if (selector == null) 
    throw Error.ArgumentNull("selector");
   return source.Provider.CreateQuery<TResult>( 
    Expression.Call( 
     null,
     ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(typeof(TSource), typeof(TResult)), 
     new Expression[] { source.Expression, Expression.Quote(selector) }
     ));
  }

   以上是对扩展方法中两个类进行了一个简单的解析。

四.扩展方法实例:

   由于扩展方法实际是对一个静态方法的调用,所以CLR不会生成代码对调用方法的表达式的值进行null值检查