2012-03-26 9 views
3

実行可能なさまざまなレポートの詳細を含む構造体配列があります。各レポートでは異なるメソッドが呼び出され、現在、プログラムは選択したレポート値を手動でチェックして、適切なメソッドを具体的に呼び出す必要があります。配列に含まれる文字列値に基づいてメソッドを呼び出す/呼び出す

私は、メソッドの名前をstruct-arrayに格納し、一致するものがあればそのメソッドを呼び出すようにします。これは可能ですか?現在

:理想的には

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

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

UPDATEは

私は疲れて以下の提案の数と、それらのどれも働きました。彼らは私のプログラムをどのように構造化したのかでおそらく動作しませんでした。

答えて

6

反射を使用することができますが、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}); 

より良いアプローチは、あなたの方法に基づいてデリゲートを定義すること、および構造体/クラスの代わりに、メソッド名に保存します。

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

デリゲートプロパティを構造体に追加し(たとえばAction型)、必要なときにこのデリゲートを呼び出すだけです。構造体インスタンスをインスタンス化するときに呼び出すメソッドにこのプロパティを設定するだけです。

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

ほとんどの人は、引数のリストを使用して、それが法であるかのようにあなたがデリゲートを呼び出すことができる代替構文を好むように見える:

3

むしろメソッド名を格納するよりも、あなたは、デリゲートを格納することができカッコ内は

MyArray[i].Method(); 

この場合、我々はMethodプロパティによって参照されるデリゲートを呼び出している、しかし、私は呼び出されている事がメソッドまたは代理人であるかどうかを曖昧にすることができるので、これを避ける傾向にありますこのコードは "メソッド"と呼ばれるメソッドへの呼び出しを表すこともできます。混乱する。簡単なスイッチをサポートするメソッド名や代表者の反射、配列を扱うよりもはるかに簡単です、私として

// 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. 
} 
2

、一つの方法は、デリゲートをキャッシュすることであろう、それらを呼び出す:

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

:すべてのメソッドは同じ署名を共有している場合

関連する問題