囚人「あの~、SqlCommand さん。ちょっといいですか?」
SqlCommand「…なんだ?」
囚人「ちょっと以下のコードを見て欲しいんですが」
C# 2.0
using(SqlConnection connection = new SqlConnection(connectionString))
{
using(SqlCommand command = new SqlCommand())
{
command.Connection = connection;
command.CommandText = query;
using(SqlDataReader reader = command.ExecuteReader())
{
…
}
}
}
Visual Basic 8.0
Using connection As New SqlConnection(connectionString)
Using command As New SqlCommand
command.Connection = connection
command.CommandText = query
Using reader As SqlDataReader = command.ExecuteReader()
…
End Using
End Using
End Using
SqlCommand「典型的な Dispose パターンだな。お手本みたいなコードじゃないか」
囚人「ええ。そうなんですけど、SqlDataReader って Dispose しても良いんですかね? 」
SqlCommand「何言ってんだ?良いに決まってるだろ?IDisposable を実装しているクラスは Dispose できる時はいつでもしとけ!この場合は自分で作ってるんだからできるだろ?」
囚人「いや、自分で作ってないですよ。作ってるのはあなたです。SqlConnection や SqlCommand、つまりあなたの事ですが、それらは私が生成しているので私が責任持って破棄します。しかし、SqlDataReader はあなたが生成しています。いや、あなたの事を疑っているわけじゃありませんよ。でもあなたが SqlDataReader のインスタンスの参照を保持しているかどうかは私にはわかりません。あなたがまだ参照しているかもしれないのに破棄してもいいんでしょうか?」
SqlCommand「完璧疑ってるじゃないか。SqlDataReader のインスタンスは参照していなし、第一、俺はその後すぐ死んでるじゃないか。何か問題あるか?」
囚人「いや、あなたの事はよく知っていますし、さっきのコードでまぁ問題ないと思うんですが、パターンとしてどうかなと」
SqlCommand「じゃあ、どんなのがいいんだ?」
囚人「以下のようなのはどうでしょうか」
C# 2.0
using(SqlConnection connection = new SqlConnection(connectionString))
{
using(SqlCommand command = new SqlCommand())
{
command.Connection = connection;
command.CommandText = query;
using(SqlDataReader reader = new SqlDataReader(command))
{
…
}
}
}
Visual Basic 8.0
Using connection As New SqlConnection(connectionString)
Using command As New SqlCommand
command.Connection = connection
command.CommandText = query
Using reader As New SqlDataReader(command)
…
End Using
End Using
End Using
囚人「これだったら、SqlDataReader は私が生成していますし、破棄の責任もあるので問題ないと思うんですよ」
SqlCommand「しかし、これだったら SqlDataReader がコンストラクタで実行されるって事になって気持ち悪くないか?」
囚人「Open() 等のメソッドを用意して、インスタンスを生成した後は Open() で SqlDataReader を開くようにします」
SqlCommand「なるほどな。でももう無理だ。俺はもう生まれているから変更できないぞ。過ぎた事をグダグダ言って結局何が言いたいんだ?」
囚人「いやね、あなたの真似をしているクラスが大勢生まれているし、これからも生まれると思うんですよ。私が言いたいのは、IDisposable を実装しているクラスはコンストラクタを公開すべきだし、IDisposable を実装しているクラスをメソッド内部で生成して戻り値で返すのは、できるだけやめた方が良いという事です」
SqlCommand「何だ?俺を手本にするなって事か?ひどくね?」