基于数组中包含的字符串值调用/调用方法

我有一个struct-array,其中包含可以运行的不同报告的详细信息。 每个报告调用一个不同的方法,当前程序必须手动检查选定的报告值以专门调用适当的方法。

我想将方法​​名存储在struct-array中,然后让程序在匹配时调用该方法。 这可能吗?

目前:

if (this.cboSelectReport.Text == "Daily_Unload") { reportDailyUnload(); } 

理想的情况是:

 if(this.cboSelectReport.Text == MyArray[i].Name) { something(MyArray[i].MethodName); } 

UPDATE

我厌倦了下面的一些建议,但没有一个有效。 他们没有工作可能是因为我的程序结构如何。

您可以使用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); } } 

您可以使用基于ActionFunc预定义类型,而不是定义自己的委托类型,具体取决于您是否需要从报告中返回值。

您可以存储委托,而不是存储方法名称:

 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”的方法的调用。 混乱。

如果所有方法共享相同的签名,则一种方法是缓存委托:

 // initialize, maybe in a constructor Dictionary nameDelegateMapping = new Dictionary(); // 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. } 

是的,你在谈论的是反思 。 这是一篇关于如何调用方法的文章 。 您可以使用谷歌在反思中找到很多。

向您的结构添加委托属性(例如,类型为Action),然后在需要时调用此委托。 只需将此属性设置为实例化struct实例时要调用的方法。

至于我,支持简单切换比处理reflection,方法名称或委托的数组,以及调用那些东西要容易得多:

 switch (reportType) { case "Daily_Unload": ReportDailyUnload(); break; // ... } 

使用delegatedictionary

 void Main() { var reports = new Dictionary { {"Daily_Unload", ReportDailyUnLoad} }; var report = "Daily_Unload"; reports[report](); } delegate string Report(); string ReportDailyUnLoad() { return "daily unload report"; }