DOBON.NET DOBON.NETプログラミング掲示板過去ログ

スクリプトの分岐処理の削減がしたい

環境/言語:[Windows Vista Visual C# 2005 .NET Framework 2.0]
分類:[.NET]

はじめまして、hiroです。
現在、C# でテキストファイルを読み込み、
書かれている命令によって処理を分岐するコードを書いていますが、
命令の分岐処理において、

// functionはstring。命令が入ってる
// argsはstring[]。引数が入ってる
if (function == "Function1")
{
Function1(args);
}
else if (function == "Function2")
{
Function2(args);
}
else if (function == "Function3")
{
Function3(args);
}

のようなコードを書いています。
functionに入ってる値と関数名は同じで、
関数側は
void Function1(params string[] args)
のようになっており、なにか無駄を感じます。
また、関数も大量に用意しているので、ifで分岐するのはかなり大変です。

このコードは省略して書く方法はありますか?
省略できるか、否か、だけでもいいので教えてください。
どなたか、回答お願いします。
■No29367に返信(hiroさんの記事)
> このコードは省略して書く方法はありますか?
public メソッドと VB の組み合わせなら、
 CallByName(対象クラス, "Function1", vbMethod, args)
の一行で済みそうなのですけれどね。

C# の場合や、private メソッドを呼び出すような場合には、
typeof(型).GetMethod メソッド等で MethodInfo を得て、
それを Invoke することで呼び出せるかと思います。
魔界の仮面弁士、回答ありがとうございます。
時間がなくて確かめていないのですが、確認ができましたらまた書き込みます。
Invokeを試してみました。voidの関数は呼び出せるようになりました。

しかし、string Function1(params string[] args)のように、stringを返す関数では、
「パラメータ カウンタが一致しません。」と表示され、うまく動作しませんでした...
voidの関数もそうなんですが、Invokeの第一引数にargsを入れているせいだと思うのですが、
Invokeの第一引数には何を入れればいいのでしょうか?

このFunction1や、分岐の処理はProgram.csとは別のクラス(Test.cs)に書かれており、
voidやstringの前には、Program.csからも呼び出せるように、static publicが書かれています。

voidの呼び出しに成功したコードは以下のとおりです。

static public void GetFunction(string function,params string[] args)
{
System.Reflection.MethodInfo mi = typeof(Test).GetMethod(function);
if (mi != null)
{
// 第一引数には一応argsを入れておく(TT)
mi.Invoke(args,args);
}
}

今までC++をやっていましたが、C#の経験は短いので、見当違いなことをやっているかもしれませんが、
どうか、引き続き回答をお願いします。
■No29373に返信(hiroさんの記事)
> しかし、string Function1(params string[] args)のように、stringを返す関数では、
> 「パラメータ カウンタが一致しません。」と表示され、
戻り値ではなく、パラメータが間違っているといわれていますよ。

Invoke 時の引数の渡し方にご注意ください。
(なお、out や ref の場合はまた違った呼び出し方が必要です)

class Program
{
  static void Main(string[] args)
  {
    //MethodInfo method1 = typeof(Program).GetMethod("Func1", new Type[] { typeof(string), typeof(string) });
    //MethodInfo method2 = typeof(Program).GetMethod("Func2", new Type[] { typeof(string[]) });
    //MethodInfo method3 = typeof(Program).GetMethod("Func3", new Type[] { typeof(string[]) });

    MethodInfo method1 = typeof(Program).GetMethod("Func1");
    MethodInfo method2 = typeof(Program).GetMethod("Func2");
    MethodInfo method3 = typeof(Program).GetMethod("Func3");

    Console.WriteLine(method1.Invoke(null, new object[] { "aaa", "bbb" }));

    Console.WriteLine(method2.Invoke(null, new object[] { new string[] { "aaa", "bbb", "ccc" } }));
    Console.WriteLine(method2.Invoke(null, new object[] { new string[] { "aaa", "bbb" } }));
    Console.WriteLine(method2.Invoke(null, new object[] { new string[] { "aaa" } }));
    Console.WriteLine(method2.Invoke(null, new object[] { new string[] { } }));
    Console.WriteLine(method2.Invoke(null, new object[] { null }));

    Console.WriteLine(method3.Invoke(null, new object[] { new string[] { "aaa", "bbb", "ccc" } }));
    Console.WriteLine(method3.Invoke(null, new object[] { new string[] { "aaa", "bbb" } }));
    Console.WriteLine(method3.Invoke(null, new object[] { new string[] { "aaa" } }));
    Console.WriteLine(method3.Invoke(null, new object[] { new string[] { } }));
    Console.WriteLine(method3.Invoke(null, new object[] { null }));

    Console.ReadKey();
  }

  public static string Func1(string a, string b)
  {
    return "Func1 :" + a + "," + b;
  }

  public static string Func2(string[] args)
  {
    return "Func2 :" + ((args == null) ? "null" : args.Length.ToString());
  }

  public static string Func3(params string[] args)
  {
    return "Func3 :" + ((args == null) ? "null" : args.Length.ToString());
  }
}

DOBON.NET | プログラミング道 | プログラミング掲示板