在下面的示例中,我想定义一个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);
}
}
}
答案 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#支持从方法到匹配签名的委托的隐式转换。