對於參數,須要使用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