Expression 表达式替代反射,包括带out参数的用法
带out参数的使用方法,研究了好一会才弄出来,网上基本上找不到样例
public static bool TryParse(string s,out uint result)
下面的代码将对上面的TryParse函数进行表达式包装,最终通过委托调用这个它
class Program
{
//Fun系列委托中,没有支持out参数的,自己定义一个
public delegate TResult FuncEx<in T1, T2, out TResult>(T1 t1, out T2 t2);
static void Main(string[] args)
{
int result = -1;
ParameterExpression param = Expression.Parameter(typeof(string));
ParameterExpression outParam = Expression.Parameter(typeof(int).MakeByRefType());
//参数类型为out类型,必须MakeByRefType()
Type[] types = new Type[] { typeof(string), typeof(Int32).MakeByRefType() };
Expression[] exps = new Expression[] { param, outParam };
ParameterExpression[] pexps = new ParameterExpression[] { param, outParam };
MethodCallExpression call = Expression.Call(typeof(Int32).GetMethod("TryParse", types), exps);
//返回委托,然后执行
FuncEx<string, int, bool> fun = Expression.Lambda<FuncEx<string, int, bool>>(call, pexps).Compile();
bool mp = fun("5", out result);
Console.WriteLine(result);
}
}
另一种不带out参数的写法
public class Program
{
static void Main(string[] args)
{
var fooExpr = Expression.Parameter(typeof(Foo), "f");
var parmExpr = Expression.Parameter(typeof(int), "i");
var method = typeof(Foo).GetMethod("Method");
var invokeExpr = Expression.Call(fooExpr, method, parmExpr);
var delegateType = MakeDelegateType(typeof(int), new[] { typeof(Foo), typeof(int) });
var lambdaExpr = Expression.Lambda(delegateType, invokeExpr, fooExpr, parmExpr);
dynamic func = lambdaExpr.Compile();
int x = 4;
int result = func (new Foo(), x);
Console.WriteLine(result);
}
private static Type MakeDelegateType(Type returnType, params Type[] parmTypes)
{
return Expression.GetDelegateType(parmTypes.Concat(new[] { returnType }).ToArray());
}
}
public class Foo
{
public int Method(int x)
{
return 8;
}
}
这是两个很简单的例子,可以在写表达式树的时候作为参考用,复杂的算法通常是很多简单的算法的叠加而已。
Posted by 何敏 on 2017/12/31 00:56:12