【问题标题】:Expression to select a method表达式选择一种方法
【发布时间】:2016-01-18 12:37:04
【问题描述】:

我正在尝试根据 Dynamically calling Moq Setup() at runtime 使用反射动态配置 Moq

在他们使用的例子中

var body = Expression.PropertyOrField( parameter, "ExampleProperty" );

创建一个表达式来选择对象的所需属性,然后使用该选择器构造一个 lambda 表达式。

我希望我的选择器改为选择一个方法,例如我想动态构造以下内容:

mock.Setup(m => m.MyMethod()).Returns(1); 

我尝试过使用:

var body = Expression.PropertyOrField(parameter, "MyMethod");

var body = Expression.MakeMemberAccess(parameter, typeof(T).GetMethod("MyMethod"));

但两者似乎都只适用于属性或字段,我可以使用不同的选择器来选择方法吗?

完整代码如下:

var mock = new Mock<T>();
var parameter = Expression.Parameter(typeof(T));

if (typeof(T).GetMethod("MyMethod") != null)
{
    var body = Expression.PropertyOrField(parameter, "MyMethod");
    var lambdaExpression = Expression.Lambda<Func<T, int>>(body, parameter);
    mock.Setup(lambdaExpression).Returns(0);
}

【问题讨论】:

  • 期待这篇文章的答案,看起来真的很有趣!抱歉这个问题:/

标签: c# lambda moq


【解决方案1】:

虽然我无法在此处访问 Moq,但我可以向您展示如何构建调用方法的 lambda 表达式

private void DoIt<T>()
{
    var mock = new Mock<T>();
    var parameter = Expression.Parameter(typeof(T));
    var methodInfo = typeof(T).GetMethod("MyMethod"); //Find the method "MyMethod" on type "T"
    if (methodInfo != null)
    {
        var body = Expression.Call(parameter, methodInfo);
        var lambdaExpression = Expression.Lambda<Func<T, int>>(body, parameter);
        //At this point, lambdaExpression is:
        //Param_0 => Param_0.MyMethod()
        mock.Setup(lambdaExpression).Returns(0);
    }
}

class MyClass 
{
    public int MyMethod() 
    {
        return 5;
    }
}

请注意,typeof(T).GetMethod("MyMethod") 不是很具体。您可以使用大量重载(或利用 GetMethods 和过滤器),它们允许您按名称、返回类型和参数类型指定方法。

另外,请注意Expression.Lambda&lt;Func&lt;T, int&gt;&gt; 仅适用于没有参数且返回int 的方法。根据负责确定方法的人员,您可能也希望具有此可配置性。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-29
    • 1970-01-01
    相关资源
    最近更新 更多