好的,首先解释一下规则:
我需要一个函数来构造一个委托,该委托匹配任何委托类型,该委托类型封装了一个主体,该主体调用一个类型为(object)(object[]args)的委托,其中“args”包含在调用期间传递给原始委托的所有参数。
我的工作到目前为止:
delegate void TestDelegate(int x, int y);
delegate object TestDelegate2(object[] args);
static void Main(string[] sargs)
{
TestDelegate d = (TestDelegate)CreateAnonymousFromType(typeof(TestDelegate));
object ret = d.DynamicInvoke(2, 6);
if (ret != null) { Console.WriteLine(ret); }
Console.ReadKey();
}
static void SpecialInvoke(int x, int y)
{
Console.WriteLine("x: {0}\r\ny: {1}", x, y);
}
static Delegate CreateAnonymousFromType(Type type)
{
MethodInfo method = type.GetMethod("Invoke");
TestDelegate2 _delegate = new TestDelegate2(
delegate(object[] args)
{
Console.WriteLine("x: {0}\r\ny: {1}", args[0], args[1]);
return "This is the return";
});
var typeargs = CreateArgs(method.GetParameters());
var argindex = -1;
var tmp = Expression.Parameter(typeof(Object), "tmp");
var index = Expression.Parameter(typeof(int), "index");
var length = Expression.Constant(typeargs.Length);
var _break = Expression.Label("breakto");
var delegateargs = Expression.Parameter(typeof(object[]), "args");
return Expression.Lambda(
type,
Expression.Block(
new[] { tmp, index, delegateargs },
Expression.Assign(index, Expression.Constant(0)),
Expression.Assign(delegateargs, Expression.NewArrayBounds(typeof(Object), length)),
Expression.Loop(
Expression.IfThenElse(Expression.LessThan(index, length),
Expression.Block(
Expression.Assign(tmp, Expression.Convert(typeargs[++argindex], typeof(Object))),
Expression.Assign(Expression.ArrayAccess(delegateargs, index), tmp),
Expression.PostIncrementAssign(index)
),
Expression.Break(_break)
),
_break
),
Expression.Call(_delegate.Method, delegateargs)
),
typeargs
).Compile();
}
static ParameterExpression[] CreateArgs(ParameterInfo[] _params)
{
ParameterExpression[] ret = new ParameterExpression[_params.Length];
for (int i = 0; i < ret.Length; i++)
ret[i] = Expression.Parameter(_params[i].ParameterType, _params[i].Name);
return ret;
}
现在这一排序工作…我只得到传递给委托“testdelegate2”的typeargs[0]的值,对于参数x和y,运行时的“args”参数是object[]2,2,在我的生命中,找不到在参数迭代范围内增加“argindex”的方法…编译时的参数计数不确定。
有人知道我怎么解决这个问题吗?
我试过使用expression.newarrayinit(typeof(object),typeargs)复制参数数组,但没有说它不能使用int32初始化对象数组。
我也尝试过:
var参数=表达式。常量(typeargs);
访问“index”处“arguments”的值,但这会生成字符串“x”和“y”。显然,这些论点的名字,而不是它们的价值观。
老实说,这是我第一次尝试使用表达式树,所以有什么帮助。不管多小。会很感激的。
谢谢您。