Ruby を使うようになってから、C# でもコードブロックを受け取るメソッドを多様するようになった。
public static class DatabaseHelper { public static bool Transaction(this Database db, Action<Database> block, int retryCount) { bool success = false; for (int i = 0; i <= retryCount; i++) { using(TransactionScope ts = new TransactionScope()) { try { block(db); success = true; ts.Complete(); break; } catch (Exception ex) { // 例外情報を保持しておいて、リトライに全て失敗したら // まとめてスローする方がいいかも。 success = false; } } } return success; } }
// トランザクションをかけてクエリを実行。 // 失敗したら3回までリトライする。 Database database = new Database(connectionString); database.Transaction(db => { db.ExecuteCommand(command); }, 3);
匿名メソッドは、外側のローカル変数も参照できるので、非常に強力。
この手法をリファクタリングで使えば、メソッドの抽出では共通化できなかったコードでも、共通化できたりする。かなり便利。