1

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

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 这样的函数,它可以根据其他地方的代码动态接受不同类型的参数?

对不起,如果我在这里含糊不清,但我以前从未见过这个,我很好奇。

4

5 回答 5

4

我认为您缺少的是 // 方法未定义的事实Invoke-它们BeginInvoke是由编译器为委托类型自动生成的。EndInvokeDelegate

当您最初声明时

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.BeginInvoke。没什么神秘的。

于 2009-03-27T06:35:48.690 回答
2

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

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

当然,我可能是错的。

于 2009-03-27T05:30:03.280 回答
0

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

于 2009-04-29T16:27:04.517 回答
0

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

编辑:

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

如果您正在寻找如何在不重载的情况下接受不同的参数,请使用:

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.
于 2009-03-27T05:20:33.643 回答
0

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

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"); });
于 2009-03-27T05:42:05.997 回答