【问题标题】:Method parameters seem dynamic, not sure how this works方法参数似乎是动态的,不确定它是如何工作的
【发布时间】:2010-10-15 21:00:11
【问题描述】:

如果我有委托和方法

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

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

【问题讨论】:

    标签: c# delegates dynamic-languages


    【解决方案1】:

    这称为方法重载。你可以找到教程here

    编辑:

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

    如果您想了解如何在不重载的情况下接受不同的参数,请使用:

    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.
    

    【讨论】:

    • 我知道什么是重载,但这不一样。
    【解决方案2】:

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

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

    当然,我可能是错的。

    【讨论】:

      【解决方案3】:

      不清楚你想做什么。如果您想知道如何创建具有不同参数的新委托,您可以这样做:

      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"); });
      

      【讨论】:

        【解决方案4】:

        我认为您缺少的是 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.BeginInvoke的签名。没什么神秘的。

        【讨论】:

          【解决方案5】:

          这不是你能做的。你还不如编译器厉害!

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2023-03-22
            • 1970-01-01
            • 2015-04-26
            • 1970-01-01
            • 2013-06-16
            • 1970-01-01
            • 1970-01-01
            • 2015-09-02
            相关资源
            最近更新 更多