对于参数,须要使用Expression.Parameter建立ParameterExpression对象,注意须要在建立Lambda时传入ParameterExpression数组才能够使参数有效。swift
对于本地变量,首先Expression类型提供Variable方法,可是这个Variable方法返回的也是ParameterExpression,实际上他们内部建立的都是同一种ParameterExpression对象,惟一的区别是Parameter方法会考虑Type.IsByRef的状况,可是Variable会抛出异常(若是Type.IsByRef为True)。其次须要注意的是,局部变量须要在建立BlockExpression时以ParameterExpression数组的方式传入。api
对于返回值,须要先经过Expression.Label的部分重载建立LabelTarget对象,接着经过Expression的Return方法(间接调用MakeGoto)返回GotoExpression,注意是和一个LabelTarget对象相关联的。最后用Expression.Label的另外一部分返回LabelExpression的重载建立Label表达式,也就是Label在代码块中的具体位置。最后LabelTarget对象能够按照类型标记,也能够按照类型连同名称标记。数组
下面代码,咱们要建立一个和以下方法相似的Lambda:async
static string doo(int i)
{
string str = i.ToString();
return str;
}
所有代码:ide
//+ using System.Reflection;
//+ using System.Linq.Expressions;
//参数
var pa = Expression.Parameter(typeof(int), "i");
//本地变量
var loc = Expression.Variable(typeof(string), "str");
//建立LabelTarget用来返回值
LabelTarget labelTarget = Expression.Label(typeof(string));
//调用i.ToString()
MethodCallExpression med = Expression.Call(pa, typeof(object).GetMethod("ToString", new Type[] { }));
//将结果赋值给本地字符串变量
BinaryExpression asn = Expression.Assign(loc, med);
//建立返回表达式(实际上就是Goto表达式)
GotoExpression ret = Expression.Return(labelTarget, loc);
//建立返回表达式的目标Label
LabelExpression lbl = Expression.Label(labelTarget, Expression.Constant(String.Empty));
//生成BlockExpression
BlockExpression blocks = Expression.Block(
new ParameterExpression[] { loc },
asn,
ret,
lbl);
//生成Lambda表达式
Expression<Func<int, string>> lam = Expression.Lambda<Func<int, string>>(blocks,
new ParameterExpression[] { pa });
//运行并输出结果
Func<int, string> del = lam.Compile();
Console.WriteLine(del(17));
输出:google
17