我有一个struct-array,其中包含可以运行的不同报告的详细信息。每个报告调用一个不同的方法,目前程序必须手动检查选定的报告值以专门调用适当的方法。
我想将方法名存储在struct-array中,然后让程序在匹配时调用该方法。这可能吗?
目前:
if (this.cboSelectReport.Text == "Daily_Unload")
{
reportDailyUnload();
}
理想情况下:
if(this.cboSelectReport.Text == MyArray[i].Name)
{
something(MyArray[i].MethodName);
}
更新
我厌倦了下面的一些建议,但没有一个有效。他们没有工作可能是因为我的程序结构如何。
答案 0 :(得分:6)
你可以使用 reflection 来实现它,但IMO它太脆弱了:它会对你调用的方法的名称引入一种不可见的依赖。
// Assuming that the method is static, you can access it like this:
var namedReportMethod = "MyReport1";
var reportMethod = typeof(ReporterClass).GetMethod(namedReportMethod);
var res = reportMethod.Invoke(null, new object[] {reportArg1, reportArg2});
更好的方法是根据您的方法定义委托,并将其存储在struct / class而不是方法名称中。
delegate void ReportDelegate(int param1, string param2);
class Runner {
public static void RunReport(ReportDelegate rd) {
rd(1, "hello");
}
}
class Test {
static void TestReport(int a, string b) {
// ....
}
public static void Main(string[] args) {
Runner.RunReport(TestReport);
}
}
您可以使用基于Action<T1,T2,...>
或Func<T1,T2,R>
的预定义类型,而不是定义自己的委托类型,具体取决于您是否需要从报告中返回值。
答案 1 :(得分:3)
您可以存储委托:
,而不是存储方法名称struct ReportInfo
{
public string Name { get; set; }
public Action Method { get; set; }
}
//...
MyArray[0] = new ReportInfo { Name = "Daily_Unload", Action = this.reportDailyUnload };
//...
if(this.cboSelectReport.Text == MyArray[i].Name)
{
MyArray[i].Method.Invoke();
}
大多数人似乎更喜欢使用替代语法,您可以使用括号中的参数列表调用委托,就像它是一个方法一样。我倾向于避免这种情况,因为被调用的东西是方法还是代理是不明确的:
MyArray[i].Method();
在这种情况下,我们调用Method
属性引用的委托,但此代码也可以表示对名为“Method”的方法的调用。混乱。
答案 2 :(得分:2)
如果所有方法共享相同的签名,则一种方法是缓存委托:
// initialize, maybe in a constructor
Dictionary<string, Action> nameDelegateMapping = new Dictionary<string, Action>();
// setup the delegates
nameDelegateMapping.Add("Daily_Unload", reportDailyUnload);
// ... add more methods here.
// later
string methodName = this.cboSelectReport.Text;
Action action;
if (nameDelegateMapping.TryGetValue(methodName, out action))
{
action();
}
else
{
// tell user the method does not exist.
}
答案 3 :(得分:1)
是的,你所说的是reflection。 Here is an article on how to invoke a method。您可以使用谷歌在反思中找到很多。
答案 4 :(得分:1)
向您的结构添加委托属性(例如,类型为Action),然后在需要时调用此委托。只需将此属性设置为实例化struct实例时要调用的方法。
答案 5 :(得分:1)
对我来说,支持简单切换比处理反射,方法名称或委托数组以及调用这些东西要容易得多:
switch (reportType)
{
case "Daily_Unload":
ReportDailyUnload();
break;
// ...
}
答案 6 :(得分:0)
使用delegate
和dictionary<string, delegate>
void Main()
{
var reports = new Dictionary<string, Report>
{
{"Daily_Unload", ReportDailyUnLoad}
};
var report = "Daily_Unload";
reports[report]();
}
delegate string Report();
string ReportDailyUnLoad()
{
return "daily unload report";
}