110,539
社区成员
发帖
与我相关
我的任务
分享
public static IEnumerable<T> Where<T>(this IEnumerable<T> data, Func<T, bool> predicate)
{
Console.WriteLine("where");
foreach (T item in data)
if (predicate(item)) yield return item;
}
predicate已经编译为本地代码了,这个函数只能调用它,但是不能知道这个条件是什么,不能获取到"<10"这个条件。
对照看
public TResult Execute<TResult>(Expression expression)
{
string s = expression.ToString();
if (s.Contains("Where"))
{
string max = Regex.Match(s, @"x\s<\s(\d+)").Groups[1].Value;
return (TResult)foo(int.Parse(max));
}
else
{
return (TResult)foo(int.MaxValue);
}
}
很明显,这里可以得到这个查询条件,可以知道这个 < 10。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var query = from x in new Integers()
where x < 10
select x;
foreach (var item in query)
Console.WriteLine(item);
var query1 = from x in new Integers().AsEnumerable()
where x < 10
select x;
foreach (var item in query1)
Console.WriteLine(item);
}
}
class Integers : IQueryable<int>
{
private LinqToIntegerProvider provider;
private Expression expression;
public Integers()
{
provider = new LinqToIntegerProvider();
expression = Expression.Constant(this);
}
public Integers(LinqToIntegerProvider p, Expression ex)
{
provider = p;
expression = ex;
}
public IEnumerator<int> GetEnumerator()
{
return (provider.Execute<IEnumerable<int>>(Expression)).GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
throw new NotImplementedException();
}
public Type ElementType
{
get { return typeof(int); }
}
public Expression Expression
{
get { return expression; }
}
public IQueryProvider Provider
{
get { return provider; }
}
}
class LinqToIntegerProvider : IQueryProvider
{
public IQueryable<TElement> CreateQuery<TElement>(Expression expression)
{
return new Integers(this, expression) as IQueryable<TElement>;
}
public IQueryable CreateQuery(Expression expression)
{
throw new NotImplementedException();
}
public TResult Execute<TResult>(Expression expression)
{
string s = expression.ToString();
if (s.Contains("Where"))
{
string max = Regex.Match(s, @"x\s<\s(\d+)").Groups[1].Value;
return (TResult)foo(int.Parse(max));
}
else
{
return (TResult)foo(int.MaxValue);
}
}
private IEnumerable<int> foo(int max)
{
for (int i = 0; i < max; i++)
yield return i;
}
public object Execute(Expression expression)
{
throw new NotImplementedException();
}
}
}
当然,我省略了Provider解析表达式树的过程,我硬编码地视作where x < 某个值。
你可以对比下AsEnumerable和不加有什么区别,后者执行的是LINQ TO OBJECTSusing System;
using System.Collections.Generic;
//using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var query = from x in new int[] { 1, 2, 3, 4, 5 }
where x > 3
select x.ToString();
foreach (var item in query)
Console.WriteLine(item);
}
}
static class MyLinq
{
public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> data, Func<TSource, TResult> selector)
{
Console.WriteLine("select");
foreach (TSource item in data)
yield return selector(item);
}
public static IEnumerable<T> Where<T>(this IEnumerable<T> data, Func<T, bool> predicate)
{
Console.WriteLine("where");
foreach (T item in data)
if (predicate(item)) yield return item;
}
}
}
运行
select
where
4
5
Press any key to continue . . .