通过与类型参数进行反射创建动作,以代理调用

发布于 2025-01-24 13:20:31 字数 639 浏览 2 评论 0原文

给定一个简单的对象

public class Foo {
   public void RunAction(Action<int, string, byte> action) {
        Action(0, null, 0);
   }
}

,并给出了一个示例伪代码方法,该方法读取此类以通过反射获得操作类型:

public void DoProxy(object [] calledWithParameters) {
     ... some code ...
}

public void DoReflection(Foo foo) {
   var actionParameterInfo = foo.getType().getMethod("RunAction").GetParameters()[0];
   var parameterTypes = actionParameterInfo.ParameterType.GenericTypeArguments;
   // Now I have the action type and the Type[] of the necessary parameters.
}

在这种情况下,我如何动态创建一个将我的doproxy调用,并在呼叫上接收到的参数?

Given a simple object

public class Foo {
   public void RunAction(Action<int, string, byte> action) {
        Action(0, null, 0);
   }
}

And given a sample pseudo-code method that reads this class to obtain the action type via reflection:

public void DoProxy(object [] calledWithParameters) {
     ... some code ...
}

public void DoReflection(Foo foo) {
   var actionParameterInfo = foo.getType().getMethod("RunAction").GetParameters()[0];
   var parameterTypes = actionParameterInfo.ParameterType.GenericTypeArguments;
   // Now I have the action type and the Type[] of the necessary parameters.
}

In this case how could I create dynamically an Action that calls my DoProxy with the received parameters on call ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

迷荒 2025-01-31 13:20:31

您需要一个代码,将操作参数转换为数组,然后再将其传递给代理。最简单的方法是使用具有不同数量的通用参数的一组通用函数:

public static class ProxyCaller
{
    public static Action<T1> CallProxy<T1>(Action<object[]> proxy) => new Action<T1>((T1 a1) => proxy(new object[] { a1 }));
    public static Action<T1, T2> CallProxy<T1, T2>(Action<object[]> proxy) => new Action<T1, T2>((T1 a1, T2 a2) => proxy(new object[] { a1, a2 }));
    public static Action<T1, T2, T3> CallProxy<T1, T2, T3>(Action<object[]> proxy) => new Action<T1, T2, T3>((T1 a1, T2 a2, T3 a3) => proxy(new object[] { a1, a2, a3 }));
    // More of these if number of arguments can be 4, 5 etc.

    public static object CreateAction(Action<object[]> proxy, Type[] parameterTypes)
    {
        var genericMethod = typeof(ProxyCaller).GetMethods().Where(m => m.Name == nameof(ProxyCaller.CallProxy) && m.GetGenericArguments().Length == parameterTypes.Length).First();
        var method = genericMethod.MakeGenericMethod(parameterTypes);
        var action = method.Invoke(null, new object[] { proxy });
        return action;
    }
}

然后在doreflection()中:

var parameterTypes = actionParameterInfo.ParameterType.GenericTypeArguments;
var action = ProxyCaller.CreateAction(DoProxy, parameterTypes);
// action has type Action<int, string, byte> here

You need a code which convert action parameters to an array before passing to a proxy. The easiest way is to use set of generic functions with different number of generic arguments:

public static class ProxyCaller
{
    public static Action<T1> CallProxy<T1>(Action<object[]> proxy) => new Action<T1>((T1 a1) => proxy(new object[] { a1 }));
    public static Action<T1, T2> CallProxy<T1, T2>(Action<object[]> proxy) => new Action<T1, T2>((T1 a1, T2 a2) => proxy(new object[] { a1, a2 }));
    public static Action<T1, T2, T3> CallProxy<T1, T2, T3>(Action<object[]> proxy) => new Action<T1, T2, T3>((T1 a1, T2 a2, T3 a3) => proxy(new object[] { a1, a2, a3 }));
    // More of these if number of arguments can be 4, 5 etc.

    public static object CreateAction(Action<object[]> proxy, Type[] parameterTypes)
    {
        var genericMethod = typeof(ProxyCaller).GetMethods().Where(m => m.Name == nameof(ProxyCaller.CallProxy) && m.GetGenericArguments().Length == parameterTypes.Length).First();
        var method = genericMethod.MakeGenericMethod(parameterTypes);
        var action = method.Invoke(null, new object[] { proxy });
        return action;
    }
}

and then in DoReflection():

var parameterTypes = actionParameterInfo.ParameterType.GenericTypeArguments;
var action = ProxyCaller.CreateAction(DoProxy, parameterTypes);
// action has type Action<int, string, byte> here
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文