2010/12/10

[C#]フォルダ内のすべてのファイルを返す

このエントリーをはてなブックマークに追加

string [] fileList = Directory.GetFiles(fontFolder,"*",SearchOption.AllDirectories);

終わり。
一行でした。

三番目のパラメータを省略するか、SearchOption.TopDirectoryOnlyを指定すると、サブフォルダまでは潜らずに指定のフォルダ直下のファイルだけを探してくれます。

昔書いたコード見てたら、意気揚々と関数化されていました。こんな再帰つくらんでもよかった。

private IEnumerable<string> GetFiles(string folder) {
foreach (string dirName in Directory.GetDirectories(folder)) {
foreach (string fileName in this.GetFiles(dirName)){
yield return fileName;
}
}

foreach (string fileName in Directory.GetFiles(folder)) {
yield return fileName;
}
}

yield使ってるということは、C#2.0以降ということなので、上の書き方もできたはず。
しかしまあ、MacG4混在環境ならGetFilesは使えないので、Directory.GetFilesのところをWindowsAPIの関数に書き換えて自作するのは仕方ないです。

それはそうと、yieldを使った再帰ってもうちょっとマシな書き方ないのかと思う。

2010/12/08

[C#]メソッド/プロパティを文字列で指定して実行する

このエントリーをはてなブックマークに追加
クラスのメソッドやプロパティを文字列を指定して呼び出しを行う方法です。

まずは手順解説

①MethodInfoを取得する
まず、TypeクラスのGetMethodメソッド(または、GetPropertyメソッド)を使用して、MethodInfoを取得します。このとき引数にメソッドに相当する文字列を指定します。
該当するメソッドが存在しない場合は、戻り値はnullになります。

②Invokeメソッドから呼び出す
呼び出し方は、MethodInfoのInvokeメソッドを使用します。引数に、呼び出し元のインスタンスと、呼び出したメソッドの引数を配列で指定します。引数がない場合は、nullを指定してください。

ソースコード
stringのToUpperメソッドを呼び出すには下のように書きます。
string hoge = "hogehoge";

// string hogeUpper = hoge.ToUpper();
// 上記ToUpperメソッドの呼び出しに相当する書き方は下記の通り。

// ①MethodInfoを取得する
MethodInfo method = typeof(string).GetMethod("ToUpper");

// ②Invokeメソッドから呼び出す
string hogeUpper = method.Invoke(hoge, null).ToString();

この手の説明では、ここでいうメソッドが、どのメソッドのことを指すのかが紛らわしくなってしまいますが、あしからず。

文字列呼び出しを関数化する
文字列で指定したメソッドを呼び出す関数です。
// using System.Reflection;
private object MethodInvoke<t>(T instance, string methodName,object[] param) {
    Type type = typeof(T);
    MethodInfo method = type.GetMethod(methodName);
    if (method == null) {
        return null;
    }
    return method.Invoke(instance,param);
}

書いてはみたものの、ぜんぜん便利そうなメソッドではないですね。
まあこんなの使わないで、普通に呼び出ししたほうが面倒くさくなくていいです。

おまけ

プロパティを指定するには、GetPropertyを呼び出します。
PropertyInfoは、それぞれGetとSetを持っていて、メソッドとして呼び出しできるようになっております。もちろん、Setが許可されていないPropertyには使えません。

プロパティのGetの取得メソッドがGetGetMethodメソッドになります。
よくわかりませんね。英語に訳すと大変なことになりそうです。

GetGetMethodを取得するメソッドを書いてみましょう。
private MethodInfo GetGetGetMethod() {
    Type type = typeof(PropertyInfo);
    return type.GetMethod("GetGetMethod");
}
GetGetGetMethodって書きたかっただけでした…。

@IT - 文字列で指定したメソッドを呼び出すには?
http://www.atmarkit.co.jp/fdotnet/dotnettips/389methodinvoke/methodinvoke.html