配列の中から、「ある条件に一致するものを探す」ような場面ではSystem.Array クラスのジェネリックメソッドが使える。例えば
など。これらのメソッドの引数にPredicateデリゲートを渡す必要がある。このデリゲートには「ある条件に一致かどうか」を返す処理を実装する。
public void Execute()
{
string[] animals ={ "cat", "dog", "pig", "bear" };
Console.WriteLine(Array.Exists(animals, new Predicate(StartWithP)).ToString());
Console.WriteLine(Array.Find(animals, new Predicate(StartWithP)));
Console.WriteLine(Array.FindIndex(animals, new Predicate(StartWithP)).ToString());
}
//"p"で始まるかどうかを判定する
private bool StartWithP(string value)
{
return (value.StartsWith("p"));
}
ただし、これだと「ある条件」が固定となってしまう。
条件を動的にするには以下のように変数を使用すればよいが、以下のようにExecuteメソッドの外に宣言しなければならない。
private string _condition;
public void Execute()
{
string[] animals ={ "cat", "dog", "pig", "bear" };
_condition = "p";
Console.WriteLine(Array.Exists(animals, new Predicate(StartWith)).ToString());
Console.WriteLine(Array.Find(animals, new Predicate(StartWith)));
Console.WriteLine(Array.FindIndex(animals, new Predicate(StartWith)).ToString());
}
//指定の文字列で始まるかどうかを判定
private bool StartWith(string value)
{
return (value.StartsWith(_condition));
}
ここはこの変数のスコープをExecuteメソッド内としたいところ。
なるほど、ここで匿名メソッドが使える。匿名メソッドではその外部のメソッド内のローカル変数にもアクセス可能であるため、条件を示す変数もExecuteメソッド内に宣言できる。
public void Execute()
{
string[] animals ={ "cat", "dog", "pig", "bear" };
string condition = "p";
//匿名メソッドで指定文字列から始まるかを返すメソッドを定義
Predicate d = delegate(string value) { return (value.StartsWith(condition)); };
Console.WriteLine(Array.Exists(animals, d).ToString());
Console.WriteLine(Array.Find(animals, d));
Console.WriteLine(Array.FindIndex(animals, d).ToString());
}
これは便利だ
コメント
コメントを投稿