小编给大家分享一下Linq中如何实现Linq Func
创新互联公司是一家专注于成都网站制作、成都做网站、外贸营销网站建设与策划设计,垦利网站建设哪家好?创新互联公司做网站,专注于网站建设十多年,网设计领域的专业建站公司;建站业务涵盖:垦利等地区。垦利做网站价格咨询:18982081108
在Linq中,任何接收λ表达式(委托类型)的方法都可以转换为接收相同委托类型的Expression
privatestaticvoid DoSomething(Predicatepredicate)
可以替换为:
privatestaticvoid DoSomething( Expression> predicate)
在上述两种情况下,调用代码可以是相同的λ表达式:
DoSomething(x => x.Value > 25);
这里发生的情况是,编译器不会将指针传入到第二个方法签名的匿名委托中,而是生成以表达式树的形式构建AST(抽象语法树)的IL代码。如果您打开Reflector(我的类型反射类的名字也由此而来,它是任何高级开发人员都应该经常使用的最伟大的工具)并取消对DoSomething的方法调用,就可以看到:
ParameterExpression expression1 = Expression.Parameter(typeof(Mock), "x"); Program.DoSomething( Expression.Lambda>( Expression.GT(Expression.Field( expression1, fieldof(Mock.Value)), Expression.Constant(0x19, typeof(int))), newParameterExpression[]{expression1 }) );
这里您可以看到编译器如何使用Expression类上的静态方法构建整个表达式(我对API的详细看法另外单独讨论)。当然,在方法实现中,您可以检查相同的树并执行任何想执行的操作。***的Linq CTP包含一个非常酷的可视化工具,在运行时到达您的方法主体时可以用来查看表达式树中的情况。到现在为止,您应该明白了我正在实现一个强类型反射:我接收一个表达式树,并在其中搜索方法调用节点(或者,对于属性和字段来说是成员访问)。下面是Method<>方法的实现:
publicstaticMethodInfo Method( Expression method) { return GetMethodInfo(method); } privatestaticMethodInfo GetMethodInfo(Expression method) { LambdaExpression lambda = method asLambdaExpression; if (lambda == null) thrownewArgumentNullException("method"); MethodCallExpression methodExpr = null; // 我们的Operation 返回一个对象,故首先可以声名一 // 个类型转换(如果方法无返回对象)或直接方法调用。 if (lambda.Body.NodeType == ExpressionType.Cast) { // 类型转换是一个一元操作,而操作数是一个方法调用表达式。 methodExpr = ((UnaryExpression)lambda.Body). Operand asMethodCallExpression; } elseif (lambda.Body.NodeType == ExpressionType.MethodCall || lambda.Body.NodeType == ExpressionType.MethodCallVirtual) { methodExpr = lambda.Body asMethodCallExpression; } if (methodExpr == null) thrownewArgumentException("method"); return methodExpr.Method; }
我创建的就是Operation委托类型。不能使用Linq Func
publicdelegateobjectOperation(); publicdelegateobjectOperation(T declaringType); publicdelegateobjectOperation(T declaringType, A0 arg0); ...
注意,API的用户从来都不会知道这些委托类型的对象的存在,就像查询操作符的用户从不知道Func
以上是“Linq中如何实现Linq Func