方法参数似乎是动态的,不确定它是如何工作的

发布于 2024-07-16 02:41:41 字数 457 浏览 4 评论 0原文

如果我有一个委托和一个方法

public delegate void SomeDelegate(String p);

void aMethod(String p) {
}

然后我尝试在新线程上调用它,就像这样

SomeDelegate sd = new SomeDelegate(aMethod());
sd.BeginInvoke("heyhey", callBack, null)

BeginInvoke 方法调用现在接受一个字符串作为第一个参数,但是,如果我从委托和 aMethod 中删除“String p” (),BeginInvoke 现在只需要两个参数。

如何构建像 BeginInvoke 这样的函数,根据其他地方的代码动态接受不同类型的参数?

抱歉,如果我在这里含糊其词,但我以前从未见过这个,我很好奇。

If I have a delegate and a method

public delegate void SomeDelegate(String p);

void aMethod(String p) {
}

And then I try to invoke this on a new thread like so

SomeDelegate sd = new SomeDelegate(aMethod());
sd.BeginInvoke("heyhey", callBack, null)

The BeginInvoke method call now accepts a string as the first parameter, however, if I remove the "String p" from the delegate and the aMethod(), BeginInvoke now only requires two parameters.

How can I build a function like BeginInvoke that dynamically accepts different types of parameters based on code elsewhere?

Sorry If Im being vague here but I've never seen this before and I'm very curious.

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

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

发布评论

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

评论(5

椒妓 2024-07-23 02:41:41

我认为您缺少的是 Invoke/BeginInvoke/EndInvoke 方法未在 Delegate - 它们由编译器自动为委托类型生成。

当您最初声明

public delegate void SomeDelegate(String p);

编译器时,会生成:(

public class SomeDelegate : Delegate
{
    public SomeDelegate(Object target, IntPtr method) { ... }

    public virtual IAsyncResult BeginInvoke(string p, 
        AsyncCallback callback, object @object) { ... }

    public virtual void EndInvoke(IAsyncResult result) { ... }

    public virtual void Invoke(string p) { ... }
}

具有适当的方法体、属性等)。

当您更改 SomeDelegate 的签名以删除参数时,生成的类型将更改为:

public class SomeDelegate : Delegate
{
    public SomeDelegate(Object target, IntPtr method) { ... }

    public virtual IAsyncResult BeginInvoke(
        AsyncCallback callback, object @object) { ... }

    public virtual void EndInvoke(IAsyncResult result) { ... }

    public virtual void Invoke() { ... }
}

没有什么真正动态发生的 - 您更改了 SomeDelegate 的签名,这会更改 SomeDelegate 的签名。开始调用。 没什么神秘的。

I think what you're missing is the fact that the Invoke/BeginInvoke/EndInvoke methods aren't defined on Delegate - they're automatically generated for the delegate type by the compiler.

When you originally declare

public delegate void SomeDelegate(String p);

the compiler generates:

public class SomeDelegate : Delegate
{
    public SomeDelegate(Object target, IntPtr method) { ... }

    public virtual IAsyncResult BeginInvoke(string p, 
        AsyncCallback callback, object @object) { ... }

    public virtual void EndInvoke(IAsyncResult result) { ... }

    public virtual void Invoke(string p) { ... }
}

(with appropriate method bodies, attributes etc).

When you change the signature of SomeDelegate to remove the parameter, the generated type changes to:

public class SomeDelegate : Delegate
{
    public SomeDelegate(Object target, IntPtr method) { ... }

    public virtual IAsyncResult BeginInvoke(
        AsyncCallback callback, object @object) { ... }

    public virtual void EndInvoke(IAsyncResult result) { ... }

    public virtual void Invoke() { ... }
}

There's nothing really dynamic going on - you changed the signature of SomeDelegate, and that changes the signature of SomeDelegate.BeginInvoke. Nothing mysterious.

谎言月老 2024-07-23 02:41:41

我相信这就是 Intellisense 为代表们做的工作。

您可以使用 params 关键字定义一个方法,让一个方法接受可变数量的参数,但在 C# 4.0 发布之前(它具有可选参数和命名参数),我不确定您可以自己做类似的事情。

当然,我可能是错的。

I believe that is Intellisense doing it's job for delegates.

You could probably define a method with the params keyword to have a method accept a variable amount of parameters, but until C# 4.0 is released (it has optional and named parameters), I'm not sure you can do stuff like that yourself.

Of course, I could be wrong.

哆啦不做梦 2024-07-23 02:41:41

不太清楚你想做什么。 如果您想知道如何创建具有不同参数的新委托,请执行以下操作:

public delegate void SomeDelegate(String p, string q);
private static void aMethod(string p, string q) 
{
    Console.WriteLine(p + q);
}

并使用委托:

SomeDelegate sd = new SomeDelegate(aMethod);
sd.BeginInvoke("heyhey", "yoyo" callback, null);

另一方面,如果您想通过调用方法来启动新线程而不需要先前定义的委托,则可以使用:

ThreadPool.QueueUserWorkItem(delegate { aMethod("heyhey", "yoyo"); });

It's not quite clear what you want to do. If you want to know how to create a new delegate with different parameters you do it as:

public delegate void SomeDelegate(String p, string q);
private static void aMethod(string p, string q) 
{
    Console.WriteLine(p + q);
}

and to use the delegate:

SomeDelegate sd = new SomeDelegate(aMethod);
sd.BeginInvoke("heyhey", "yoyo" callback, null);

If on the other hand you want to start a new thread by calling a method without having a previously defined delegate you can use:

ThreadPool.QueueUserWorkItem(delegate { aMethod("heyhey", "yoyo"); });
我也只是我 2024-07-23 02:41:41

这称为方法重载。 您可以在此处找到教程。

编辑:

那么我可能误解了你的问题。

如果您正在寻找如何接受不同的参数而不重载,您可以使用:

public void MyMethod(params object[] args)
{
  foreach (object o in args)
  {
    Type t=o.GetType();
    // do something with o depending on the type
    if (t==typeof(int))
    {
      int i=(int)o; 
      // ...
    }
    else if (t==typeof(string)) // etc.
    {
    }
  }
}

然后您可以调用:

MyMethod(5, "foo", 7.77);
MyMethod("foo", "bar");
// etc.

This is called method overloading. You can find a tutorial here.

EDIT:

Then I probably misunderstood your question.

If you a looking how to accept different parameters without overloading you use:

public void MyMethod(params object[] args)
{
  foreach (object o in args)
  {
    Type t=o.GetType();
    // do something with o depending on the type
    if (t==typeof(int))
    {
      int i=(int)o; 
      // ...
    }
    else if (t==typeof(string)) // etc.
    {
    }
  }
}

You can then call:

MyMethod(5, "foo", 7.77);
MyMethod("foo", "bar");
// etc.
云朵有点甜 2024-07-23 02:41:41

这不是你能做的事。 你还没有编译器强大!

This is not something you can do. You are not as powerful as the compiler!

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