Value types inferred as object at runtime when using dynamic

戏子无情 提交于 2019-12-06 10:31:42

This isn't specific to dynamic. You will get the same result if you replace dynamic with object. You would even get that for custom value types that implement an interface and you want to return them from a Func<IImplementedInterface>.
The reason for this is the fact that when you want to return an int as object it has to be boxed - as you correctly guessed.
The expression that is used for boxing is Expression.Convert. Adding that to your code will fix the exception:

private static Expression<Func<T, dynamic>> BuildDynamicExpression<T>(
    T arg,
    MethodInfo method)
{
    ParameterExpression param = Expression.Parameter(typeof(T));
    var methodCall = Expression.Call(param, method);
    var conversion = 
    return Expression.Lambda<Func<T, dynamic>>(
        Expression.Convert(methodCall, typeof(object)),
        new ParameterExpression[] { param });
}

BTW: As you can see, I removed the args array. It is not necessary.


To work around the problem with Moq I think you need to change the approach a bit.
The idea is the following:

  • Create an expression with the exact return type of the called method.
  • Let the DLR (Dynamic Language Runtime) figure out the type of the expression.

In Code:

IEnumerable<Expression> results =
    typeof(ITestCase2).GetMethods()
                      .Select(m => BuildDynamicExpression(
                                       new TestCase2Impl(), m));

BuildDynamicExpression looks like this:

private static Expression BuildDynamicExpression<T>(T arg, MethodInfo method)
{
    ParameterExpression param = Expression.Parameter(typeof(T));
    return Expression.Lambda(Expression.Call(param, method),
                             new ParameterExpression[] { param });
}

Usage would be like this:

foreach(var expression in results)
{
    mock.Setup((dynamic)expression);
    // ...
}

The important part here is the cast to dynamic before passing the expression to Setup.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!