C# 使用DLR调用带有ref参数的方法
尝试调用使用ref参数的示例方法:C# 使用DLR调用带有ref参数的方法,c#,dynamic,C#,Dynamic,尝试调用使用ref参数的示例方法: public void RefTest(ref int i) { Console.WriteLine(i); i = 18; } 利用DLR: var prog = new Program(); var binder = Microsoft.CSharp.RuntimeBinder.Binder.InvokeMember( CSharpBinderFlags.ResultDiscarded, "RefTest", null,
public void RefTest(ref int i)
{
Console.WriteLine(i);
i = 18;
}
利用DLR:
var prog = new Program();
var binder = Microsoft.CSharp.RuntimeBinder.Binder.InvokeMember(
CSharpBinderFlags.ResultDiscarded,
"RefTest", null, typeof(Program),
new CSharpArgumentInfo[]{
CSharpArgumentInfo.Create(0,null),
CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.IsRef,null)
}
);
ParameterExpression p = Expression.Parameter(typeof(int));
Expression dyn = Expression.Dynamic(binder, typeof(object), Expression.Constant(prog), p);
var lam = Expression.Lambda<Action<int>>(dyn, p).Compile();
lam(9); //RuntimeBinderException
var prog=new Program();
var binder=Microsoft.CSharp.RuntimeBinder.binder.InvokeMember(
CSharpBinderFlags.resultdiscared,
“RefTest”,空,类型(程序),
新CSharpArgumentInfo[]{
CSharpArgumentInfo.Create(0,null),
CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.IsRef,null)
}
);
ParameterExpression p=表达式.参数(typeof(int));
表达式dyn=表达式动态(活页夹、类型(对象)、表达式常量(程序)、p);
var lam=Expression.Lambda(dyn,p).Compile();
林(9),//RuntimeBinderException
但是,代码失败,RuntimeBinderException无法将int转换为ref int。如何修复它
我试图模仿以下代码:
dynamic prog = new Program();
Action<int> lam = i => prog.RefTest(ref i);
lam(9);
dynamic program = ...;
program.RefTest(ref myInt);
Expression programExpr = Expression.Constant(program);
var binder = Binder.InvokeMember(CSharpBinderFlags.ResultDiscarded | CSharpBinderFlags.InvokeSimpleName, "Bla", null, typeof (Program),
new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.IsRef, null) });
var intParam = Expression.Parameter(typeof (int).MakeByRefType(), "x");
Expression methodCall = Expression.Dynamic(binder, typeof (void), programExpr, intParam);
var expr = Expression.Lambda<RefAction<int>>(methodCall, intParam).Compile();
expr(ref myInt);
dynamic prog=新程序();
动作lam=i=>程序参考测试(参考i);
林(9),;
我必须使用DLR而不是反射,因为提供的对象(prog
)可能是动态的。如果我没有错的话。参考
Alexandra Rusina在链接线程和中的回答
尝试以下操作(无法编译):
简单动态不支持ref/out。因此,显然,在表达式中尝试同样的方法也不会奏效。我重现了您的问题,并发现了有关代码的一些潜在问题。为了解释,我将从如何解释您实际尝试执行的操作开始,即运行以下代码:
dynamic prog = new Program();
Action<int> lam = i => prog.RefTest(ref i);
lam(9);
dynamic program = ...;
program.RefTest(ref myInt);
Expression programExpr = Expression.Constant(program);
var binder = Binder.InvokeMember(CSharpBinderFlags.ResultDiscarded | CSharpBinderFlags.InvokeSimpleName, "Bla", null, typeof (Program),
new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.IsRef, null) });
var intParam = Expression.Parameter(typeof (int).MakeByRefType(), "x");
Expression methodCall = Expression.Dynamic(binder, typeof (void), programExpr, intParam);
var expr = Expression.Lambda<RefAction<int>>(methodCall, intParam).Compile();
expr(ref myInt);
请注意,上面的代码工作正常,并运行该方法
这里有几点需要注意:
变量是一个常量程序
- 该方法返回
void
- 我们应该能够通过引用传入任何整数
- 您的
调用告诉方法返回表达式.Dynamic
。相反,它应该返回对象
typeof(void)
- 您的
调用将委托类型指定为表达式.Lambda
操作。参数的类型应为
。要解决这个问题,应该有一个ref int
,它具有操作
参数<代码>委托无效重构(参考T arg1)ref
dynamic prog = new Program();
Action<int> lam = i => prog.RefTest(ref i);
lam(9);
dynamic program = ...;
program.RefTest(ref myInt);
Expression programExpr = Expression.Constant(program);
var binder = Binder.InvokeMember(CSharpBinderFlags.ResultDiscarded | CSharpBinderFlags.InvokeSimpleName, "Bla", null, typeof (Program),
new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.IsRef, null) });
var intParam = Expression.Parameter(typeof (int).MakeByRefType(), "x");
Expression methodCall = Expression.Dynamic(binder, typeof (void), programExpr, intParam);
var expr = Expression.Lambda<RefAction<int>>(methodCall, intParam).Compile();
expr(ref myInt);
虽然是关于
out
而不是ref
,但同样的问题适用,同样的答案解决,除非我遗漏了进一步的区别。@Jon错了。这使用DLR,而不是反射。如果这是您期望的答案,那么将参数类型设置为typeof(int).MakeByRefType()
也没有帮助。@illand4另一个示例使用表达式树的方式与您相同。您是否将DLR与表达式的运行时创建混为一谈?@Bas Duh,我是-您没有看到Expression.Dynamic
?@IllidanS4只是确保这是有意的。我如何理解这个问题是参数是强类型的。这只是OP要求的动态调用…@因为你可能是对的。我不确定我是否遗漏了真正的问题。我相信这是一个XY问题。在阅读了您的答案后,我相信ref和dynmaic不能很好地协同工作。感谢您的努力,但我需要使用DLR,以防对象是动态的(ref和out参数在动态对象上受支持)。@illdans4这就是为什么我提到了由于运行时错误而无法执行此操作的可能性。我希望你能解决它,但这感觉像是无法解决的事情。