如何从函数表达式中获取方法名称和参数?

时间:2010-11-17 18:17:51

标签: c# linq reflection expression-trees

示例:

由于本例范围之外的原因,我不得不使用它:

UserRepository repository = new UserRepository();
User user = (User)InvokeMethod(repository, "GetUserById", new object[]{2});

private object InvokeMethod(object source, string methodName, object[] parameters)
{
    Type sourceType = source.GetType();
    MethodInfo methodInfo = sourceType.GetMethod(methodName);
    return methodInfo.Invoke(source, parameters);            
}

但是,我更喜欢这样的事情:

UserRepository repository = new UserRepository();
User user = GetUserById<User, UserRepository>(repository, m => m.GetUserById(2));

包装器可以实现这一点。我开始建立一个,但卡住了。这就是我所拥有的:

public TUser GetUserById<TUser, TUserRepository>(TUserRepository repository, Expression<Func<TUserRepository, TUser>> repositoryFunc)
     where TUser : User
     where TUserRepoistory : UserRepository
{
    // How do I use the Expression to setup the next two statements?
    string methodName = ""; // should be "GetUserId"
    object[] params = null; // should be "object[] { 2 }"

    TUser user = (TUser)InvokeMethod(repository, methodName, parameters);
}

请记住,我被迫使用InvokeMethod方法。我不能简单地调用Func。

1 个答案:

答案 0 :(得分:4)

这会变得复杂,具体取决于参数是文字,捕获的变量等 - 以及它们是refout等。您可能希望查看protobuf-net中的实现。扩展程序here,其中包含所有这些内容的代码 - 特别是ResolveMethod方法。

MethodInfo很简单 - 只需将Body转换为MethodCallExpression并获取.Method.Name - 但对于参数,它会递归调用Evaluate - 这允许像SomeMethod(123, x, y.Foo.Bar)这样的表达式可以使用,其中123是文字,x是捕获的变量,y.Foo.Bar off 捕获的变量