如何传递方法名称以实例化委托?

时间:2009-04-17 13:51:03

标签: c# delegates

在下面的示例中,我想定义一个System.Action,它执行我在运行时定义的特定方法,但如何传递方法名称(或方法本身)以便Action方法可以定义委托以指向该特定方法吗?

我目前收到以下错误:

'methodName'是'变量',但用作'方法'

using System;
using System.Collections.Generic;

namespace TestDelegate
{
    class Program
    {
        private delegate void WriteHandler(string message);

        static void Main(string[] args)
        {
            List<string> words = new List<string>() { "one", "two", "three", "four", "five" };
            Action<string> theFunction = WriteMessage("WriteBasic");

            foreach (string word in words)
            {
                theFunction(word);
            }
            Console.ReadLine();
        }

        public static void WriteBasic(string message)
        {
            Console.WriteLine(message);
        }

        public static void WriteAdvanced(string message)
        {
            Console.WriteLine("*** {0} ***", message);
        }

        public static Action<string> WriteMessage(string methodName)
        {
            //gets error: 'methodName' is a 'variable' but is used like a 'method'
            WriteHandler writeIt = new WriteHandler(methodName);

            return new Action<string>(writeIt);
        }

    }
}

5 个答案:

答案 0 :(得分:5)

您不需要Delegate声明或WriteMessage方法。请尝试以下方法:

using System;
using System.Collections.Generic;

namespace TestDelegate
{
    class Program
    {
        static void Main(string[] args)
        {
            List<string> words = new List<string>() { "one", "two", "three", "four", "five" };
            Action<string> theFunction = WriteBasic;

            foreach (string word in words)
            {
                theFunction(word);
            }
            Console.ReadLine();
        }

        public static void WriteBasic(string message)
        {
            Console.WriteLine(message);
        }

        public static void WriteAdvanced(string message)
        {
            Console.WriteLine("*** {0} ***", message);
        }

    }
}

行动已经是一个代表,所以你不需要再做一个。

答案 1 :(得分:2)

不带引号传递 -

Action<string> theFunction = WriteMessage(WriteBasic);

将“WriteMessage”的签名更改为 -

public static Action<string> WriteMessage(WriteHandler methodName)

同时将“私人”代表更改为“公开” -

public delegate void WriteHandler(string message); //Edit suggested by Mladen Mihajlovic

答案 2 :(得分:1)

除非使用反射,否则无法传递此类方法。为什么不把WriteHandler作为参数而不是字符串?

答案 3 :(得分:0)

你可以使用反射,但不建议这样做。

为什么不让WriteMessage方法接受WriteHandler的参数?

然后你可以像这样调用它(在C#2 +中):

WriteMessage(myMethod);

答案 4 :(得分:0)

你想要Delegate.CreateDelegate。在您的具体情况下,您可能需要Delegate.CreateDelegate(Type,Type,string)

public static Action<string> WriteMessage(string methodName)
{
  return (Action<string>) Delegate.CreateDelegate (
      typeof(Action<string>),
      typeof(Program),
      methodName);
}

然而,正如Mladen Mihajlovic所说,为什么你想根据字符串创建委托吗?它会更容易 - 并由编译器检查! - 使用C#支持从方法到匹配签名的委托的隐式转换。