在 C# 中传递具有 N 个参数作为参数的方法

发布于 2024-10-20 05:53:15 字数 1226 浏览 2 评论 0原文

我有几种方法都返回带有不同签名(参数)和不同名称的 void 。我需要将这些方法作为参数传递到稍后调用它的通用方法中。此外,还需要尽可能透明。

按照我到目前为止所得到的:

    private void button1_Click(object sender, EventArgs e)
    {
        Action<string,int> TestHandler = Test;
        InvokeMyMethod(TestHandler);

        Action<string, int,object > TestHandlerN = TestN;
        InvokeMyMethod(TestHandlerN);
    }        
public void InvokeMyMethod(Delegate Method)
    {
          object[] args = new object[X];            
          Method.DynamicInvoke();
    }

    public void Test(string t1, int t2)
    {
        MessageBox.Show(t1 + t2);
    }

    public void TestN(string t1, int t2, object t3)
    {
        MessageBox.Show(t1 + t2);
    }

这就是我需要的:

    private void button1_Click(object sender, EventArgs e)
    {
        InvokeMyMethod(Test);
        InvokeMyMethod(TestN);
    }

    public void InvokeMyMethod(XXX_Type Method)
    {
         object[] args = new object[X];
         Method.DynamicInvoke(args);
    }

    public void Test(string t1, int t2)
    {
        MessageBox.Show(t1 + t2);
    }

    public void TestN(string t1, int t2, object t3)
    {
        MessageBox.Show(t1 + t2);
    }

I have several methods all returning void with different signature (parameters) and different names. I need to pass those methods as a parameter in a generic method that will invoke it latter. Also that need to be as transparent as possible.

Following what I got so far:

    private void button1_Click(object sender, EventArgs e)
    {
        Action<string,int> TestHandler = Test;
        InvokeMyMethod(TestHandler);

        Action<string, int,object > TestHandlerN = TestN;
        InvokeMyMethod(TestHandlerN);
    }        
public void InvokeMyMethod(Delegate Method)
    {
          object[] args = new object[X];            
          Method.DynamicInvoke();
    }

    public void Test(string t1, int t2)
    {
        MessageBox.Show(t1 + t2);
    }

    public void TestN(string t1, int t2, object t3)
    {
        MessageBox.Show(t1 + t2);
    }

That is what I need:

    private void button1_Click(object sender, EventArgs e)
    {
        InvokeMyMethod(Test);
        InvokeMyMethod(TestN);
    }

    public void InvokeMyMethod(XXX_Type Method)
    {
         object[] args = new object[X];
         Method.DynamicInvoke(args);
    }

    public void Test(string t1, int t2)
    {
        MessageBox.Show(t1 + t2);
    }

    public void TestN(string t1, int t2, object t3)
    {
        MessageBox.Show(t1 + t2);
    }

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

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

发布评论

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

评论(2

猫卆 2024-10-27 05:53:15

这并没有直接回答你的问题,但这是我解决类似问题的方法:

public static partial class Lambda
{
    public static Action Pin<T0>
        (
            this Action<T0> action,
            T0 arg0
        )
    {
        return () => action(arg0);
    }

    public static Func<TResult> Pin<T0, TResult>
        (
            this Func<T0, TResult> func,
            T0 arg0
        )
    {
        return () => func(arg0);
    }

    public static Action Pin<T0, T1>
        (
            this Action<T0, T1> action,
            T0 arg0,
            T1 arg1
        )
    {
        return () => action(arg0, arg1);
    }

    public static Func<TResult> Pin<T0, T1, TResult>
        (
            this Func<T0, T1, TResult> func,
            T0 arg0,
            T1 arg1
        )
    {
        return () => func(arg0, arg1);
    }

    // More signatures omitted for brevity...
    // I would love it if C# supported variadic template parameters :-)
}

这个想法是,如果你有一个需要参数的 Action ,你可以说:

Action<int, string> foo;
Action a = foo.Pin(5, "bleh");

拥有 代码生成器

同样,您可能希望有一种方法来柯里化为其他委托类型(例如 Action)。我的方法和你的方法之间的区别在于,我的方法不是后期绑定,但你似乎并没有使用后期绑定,因此早期绑定为你提供了一些编译时类型安全性。

我不确定你能做我认为你要求的事情。您使用一些 object[] 调用 method.DynamicInvoke,但是如何获取这些参数的值呢?


为了在任何人提出问题之前回答这个问题,我创建了 Lambda.Pin 函数,因为我厌倦了犯这个错误:

Action<int> foo;
foreach (int i in someList)
    AddAction(() => foo(i));

This doesn't answer your question directly, but here is how I solve a similar problem:

public static partial class Lambda
{
    public static Action Pin<T0>
        (
            this Action<T0> action,
            T0 arg0
        )
    {
        return () => action(arg0);
    }

    public static Func<TResult> Pin<T0, TResult>
        (
            this Func<T0, TResult> func,
            T0 arg0
        )
    {
        return () => func(arg0);
    }

    public static Action Pin<T0, T1>
        (
            this Action<T0, T1> action,
            T0 arg0,
            T1 arg1
        )
    {
        return () => action(arg0, arg1);
    }

    public static Func<TResult> Pin<T0, T1, TResult>
        (
            this Func<T0, T1, TResult> func,
            T0 arg0,
            T1 arg1
        )
    {
        return () => func(arg0, arg1);
    }

    // More signatures omitted for brevity...
    // I would love it if C# supported variadic template parameters :-)
}

The idea is that if you have an Action which requires arguments, you can say:

Action<int, string> foo;
Action a = foo.Pin(5, "bleh");

Have the code generator.

Likewise, you might want to have a way to curry to some other delegate type (like Action<string, int>). The difference between my method and yours is that mine is not late-bound, but you do not appear to be using late-binding anyway, so early-binding gives you some compile-time type safety.

I'm not sure you can do what I think you are asking. You call method.DynamicInvoke with some object[], but how did you get values for those parameters?


And to answer the question before anybody asks it, I created the Lambda.Pin functions because I was tired of making this mistake:

Action<int> foo;
foreach (int i in someList)
    AddAction(() => foo(i));
笑红尘 2024-10-27 05:53:15
public void InvokeMyMethod(Delegate method) {
    Method.DynamicInvoke(new object[] {"Test", 1});
}

但你需要像这样调用它

InvokeMyMethod((Action<string, int>)Test);
public void InvokeMyMethod(Delegate method) {
    Method.DynamicInvoke(new object[] {"Test", 1});
}

But you need to invoke it like

InvokeMyMethod((Action<string, int>)Test);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文