プログラミングに盲点はありますか?
つまり、慣れることができない一般的なテクニックや言語機能があるということです。まあ、私は1つ(またはおそらく複数)持っており、私の使用法はdelegate
. ハンズアップ!デリゲートに満足していない人は他にいますか? 正直に言ってください!
では、デリゲートとは何ですか?
大学でのコースで C を紹介されたので、関数ポインターについて知っています。メソッドを引数として渡したい場合は、関数ポインタが便利です。したがって、私の考えでは、デリゲートは関数ポインターのようなものです。ユーレカ!わかった。していません!
具体的なシナリオ?
正規表現に一致する行をテキスト ファイルから削除したいと考えています。行のコレクションがあると仮定すると、その目的に完全に適していると思われる
List<T>
方法があります。リスト要素を削除するか残すかを決定するための引数として、評価メソッドが必要です。関数ポインタです。RemoveAll
RemoveAll
ここにコードはありますか?
public static int RemoveLinesFromFile(string path, string pattern)
{
List<string> lines = new List<string>(File.ReadAllLines(path));
int result = lines.RemoveAll(DoesLineMatch);
File.WriteAllLines(path, lines.ToArray());
return result;
}
DoesLineMatch
行がパターンに一致するかどうかを評価する関数を探しています。
問題が見えますか?
RemoveAll
Predicate<string> match
引数としてデリゲートが必要です。次のようにコーディングします。
private static bool DoesLineMatch(string line, string pattern)
{
return Regex.IsMatch(line, pattern);
}
しかし、「'bool DoesLineMatch(string)' シグネチャを持つメソッドが必要です」というエラーが表示されます。ここで何が欠けていますか?
それはまったく機能しますか?
これが私が最終的にそれを機能させた方法です:
public static int RemoveLinesFromFile(string path, string pattern)
{
List<string> lines = new List<string>(File.ReadAllLines(path));
int result = lines.RemoveAll(delegate(string line)
{
return Regex.IsMatch(line, pattern);
});
File.WriteAllLines(path, lines.ToArray());
return result;
}
それが機能することはうれしいですが、私はそれを理解していません。
そして、質問は何ですか?
それを機能させるために私がしたことは、単にメソッドをインライン化することです。私がインライン化を理解している限り、それはある種の一度使用して破棄するコードにすぎません。変数またはメソッドを 1 回だけ使用する場合はインライン化できますが、インライン化は常に明示的に宣言することと同じです。
メソッドを明示的に宣言する方法はありますか? どうすればいいですか?
PS .: 私の質問がやや長いことをお許しください。
PPS .: このデリゲートを取得したらすぐに、2.0 から 3.0 に飛躍し、ラムダを学習します。
PPPS .:の効率に関するJon のヒントRegex.IsMatch(string, string)
に従って、コードを変更しました。
int result = lines.RemoveAll(delegate(string line)
{
Regex regex = new Regex(pattern);
return regex.IsMatch(line);
});
それは効率の問題に関してはあまり役に立ちません。そこで、ReSharperの提案に従い、正規表現のインスタンス化を外側のスコープに移動しました。
Regex regex = new Regex(pattern);
int result = lines.RemoveAll(delegate(string line)
{
return regex.IsMatch(line);
});
ReSharper は、これをメソッド グループに置き換えるように促しました。
Regex regex = new Regex(pattern);
int result = lines.RemoveAll(regex.IsMatch);
そして、それはここで提案された答えと非常に似ています。私が求めたものではありませんが、ReSharper (そしてもちろんスタック オーバーフロー) が学習にどのように役立つかに再び驚いています。