2004年12月26日

C#プログラミングレッスンNo020発行

   このエントリーをはてなブックマークに追加 Clip to Evernote
メルマガ「C#プログラミングレッスン No.020」を発行しました。今回から、装いも新たにオブジェクト指向プログラミングの話題に移ります。まずは、クラスの説明から始めます。
発行開始から約4ヶ月経ち、読者数も370人を超えました。読者数をさらに増やせるよう頑張って発行していきたいと思います。  

Posted by gushwell at 17:40Comments(0)TrackBack(1)

2004年12月22日

try-catch-finallyについて考える(5)

   このエントリーをはてなブックマークに追加 Clip to Evernote
さて、前回の結論は、try-catch-finally という構文が用意されているますが、finally処理と例外処理は、対象としているものが異なるため、
   try {
// ...
} catch {
// ...
} finally {
// ...
}
と書ける場面は、それほど多くは無い、ということでした。
それと、 「finally処理に対応する初期処理は、try ブロックの中に入れてしまう」ルールは、usingを導入することで、不要なルールとなりました。
で、再度、ソースコードを見て見ると、あることに気が付きました。もう少し、例外の補足範囲を広げて見たら、同じ構造になりそうだ、ということです。修正したコードは次のとおり。
    try {
using ( SqlConnection conn = new SqlConnection(strconn) ) {
conn.Open();
// 処理
}
} catch ( SqlException ex ) {
MessageBox.Show(ex.Message);
}

    try {
SqlCommand cmd = new SqlCommand(sqltext,conn);
using ( SqlDataReader dr = cmd.ExecuteReader() ) {
//
}
} catch ( SqlException ex ) {
MessageBox.Show(ex.Message);
}

これなら、 見た目も同じ構造になり、try-catchに統一感を持たせられますの
で、コーディングする際も、悩む必要がなさそうです。
なお、集約例外ハンドラーをどう活用するか、継続不能な例外発生時にどう対
応するかなどの「例外処理の指針」をその前に決めておく必要があるのは言う
までもありません。

  
Posted by gushwell at 21:24Comments(0)TrackBack(1)

2004年12月20日

try-catch-finallyについて考える(4)

   このエントリーをはてなブックマークに追加 Clip to Evernote
C#には、この問題を解決する方法として、using があるようです。試してみました。
まずは、Connection の Open, Close のコードでは、
    // sample1-3
using ( SqlConnection conn = new SqlConnection(strconn) ) {
try {
conn.Open();
// 処理
} catch ( SqlException ex ) {
MessageBox.Show(ex.Message);
}
}

ExecuteRead のコードでは、
    // sample2-4
SqlCommand cmd = new SqlCommand(sqltext,conn);
using ( SqlDataReader dr = cmd.ExecuteReader() ) {
try {
//
} catch ( SqlException ex ) {
MessageBox.Show(ex.Message);
}
}

と書くことができます。
しかし、しかし、前者は、例外を補足できたのですが、残念ながら、後者は、ExecuteReader内で例外が発生した場合に、例外を補足できません。まあ、文法上、当然と言えば当然ですね。

と、ここまで書いて、例外を補足しようとしている対象が異なっているのに気が付きました。前者は、using の () の中でnewしたインスタンスの処理に対する例外を補足しようとしているのに対し、後者は、using の外側で newした cmd に対する処理の例外を補足しようとしています。

似たような処理でも、本質が異なっているものを同じ処理でまかなおうとしていることに無理があるのです。
ですから、sample2-4は以下のように書く必要がでてきます。
    // sample2-5
SqlCommand cmd = new SqlCommand(sqltext,conn);
try {
using ( SqlDataReader dr = cmd.ExecuteReader() ) {
//
}
} catch ( SqlException ex ) {
MessageBox.Show(ex.Message);
}


で、結局、結論らしい結論を出せないままです。
しいて言えば、usingを使えば、「try-catch-finally構文は、catchとfinally両方を同じtry文で書く場面はほとんどないのではないか」ということです。

(続く)

  
Posted by gushwell at 22:08Comments(0)TrackBack(0)

2004年12月17日

try-catch-finallyについて考える(3)

   このエントリーをはてなブックマークに追加 Clip to Evernote
昨日の続き。

では、「finally処理に対応する初期処理は、try ブロックの中に入れてしまう」ルールを無視し、
SqlDataReader dr = cmd.ExecuteReader();
をtryの外に出してみましょう。
    // sample2-3
SqlCommand cmd = new SqlCommand(sqltext,conn);
SqlDataReader dr = cmd.ExecuteReader();
try {
//
} catch ( SqlException ex ) {
MessageBox.Show(ex.Message);
} finally {
dr.Close();
}

かなり、すっきりしました。でも、ExecuteReader 内での例外を補足できなくなってしまいました。これでは、いくらすっきりしたコードになっても意味がありません。

うーーん、やはり、try の中に入れるしかないのでしょうか。これは、インスタンスを new し、最後に、Dispose しないといけないクラスにも当てはまることになります。コンストラクタ内での例外を補足するには、やはり、new は、try の中で書く必要がありそうです。

ただ、nullで初期化したり、null かどうかを判断するコードを書くのは、どうも僕の趣味に合いません。(趣味でコードをいじくり回すな!としかられそうですが...)
(続く)  
Posted by gushwell at 21:27Comments(0)TrackBack(0)

2004年12月16日

try-catch-finallyについて考える(2)

   このエントリーをはてなブックマークに追加 Clip to Evernote
昨日の続き
では、「finally処理に対応する初期処理は、try ブロックの中に入れてしまう」というルールに沿って書いた次のコードを見てみましょう。
    // sample2-1
SqlCommand cmd = new SqlCommand(sqltext,conn);
try {
SqlDataReader dr = cmd.ExecuteReader();
// 何らかの処理
} catch ( SqlException ex ) {
MessageBox.Show(ex.Message);
} finally {
dr.Close();
}

ExecuteReadに対応する後処理が、dr.Close です。一見よさそうですが、このコードでは、ローカル変数 drの有効範囲は、try ブロックの中なので、finally 部分で、コンパイルエラーになってしまいます。そのため、以下のように書かなくてはなりません。
    // sample2-2
SqlCommand cmd = new SqlCommand(sqltext,conn);
SqlDataReader dr = null;
try {
dr = cmd.ExecuteReader();
// 何らかの処理
} catch ( SqlException ex ) {
MessageBox.Show(ex.Message);
} finally {
if ( dr != null )
dr.Close();
}

うーーん、でもこれだと、C#の宣言と初期化を一緒にできるというメリットを活かせません。それに、finally で null かどうかを判断するのは、なんかエレガントでは無いように感じます。
(続く)  
Posted by gushwell at 21:46Comments(0)TrackBack(0)

2004年12月15日

try-catch-finallyについて考える(1)

   このエントリーをはてなブックマークに追加 Clip to Evernote
以下のコードをみてください。
  // sample1-1
SqlConnection conn = new SqlConnection(strconn);
conn.Open();
try {
// 処理
} catch ( SqlException ex ) {
MessageBox.Show(ex.Message);
} finally {
conn.Close();
}

この処理は、一つ問題があります。それは、Open で例外が発生した時に、例外を補足できないことです。そのため、
    // sample1-2
SqlConnection conn = new SqlConnection(strconn);
try {
conn.Open();
// 処理
} catch ( SqlException ex ) {
MessageBox.Show(ex.Message);
} finally {
conn.Close();
}

と、Open の位置を、try ブロックの中に移動することにします。Open してい
ない状態の時に、Close を呼んでも問題ないので、これでOKです。
ここから導き出せる乱暴な結論は、 「finally処理に対応する初期処理は、try ブロックの中に入れてしまう」というものです。

しかしこれって、本当なのでしょうか。(続く)
  
Posted by gushwell at 22:00Comments(0)TrackBack(0)

2004年12月10日

クラス名? プロパティ名?

   このエントリーをはてなブックマークに追加 Clip to Evernote
int h = Font.Height;

というコードを見て、あるる程度の経験のある人ならば、Fontはプロパティ名だということが直ぐに分かると思います。でも、初心者の人には、これがプロパティ名なのか、クラス名なのかの区別が付きにくいのではないでしょうか。
僕なんかは、慣れないASP.NET のコードで、Application, Cashe, Siteなどのプロパティ名が出てくると今だに混乱します。ASP.NETのコードを始めて見た時は、Request, Responce, Session などは、クラスの名前で、その staticメソッドを呼んでいるのだと勘違いしていました。さすがに、今はそういった勘違いはなくなりましたが、クラスには、C や T といったプレフィックスを付ける流儀の方が間違いが少なくて良いのになー、なんて思ってしまいます。これには、異論が出そうですね。
とにかく、クラス名と同じ名前をプロパティ名にするのは、良いような悪いような、ですね。良く使っているクラスならばいざしらず、アプリケーションプログラマーが書いたコードで、こういったクラスがあると、頭の固い僕は思考回路が止まってしまいます。  
Posted by gushwell at 19:55Comments(2)TrackBack(0)

2004年12月07日

CSS

   このエントリーをはてなブックマークに追加 Clip to Evernote
CSSを記述していて、文字列の終端の ” を記述を忘れ、ハマってしまった。

font-family: verdana, arial,"Osaka", "MS P ゴシック";

と記述すべところが、

font-family: verdana, arial,"Osaka", "MS P ゴシック

となっていたのにまったく気が付かず、なぜ、表示が意図した通りにならないのかと悩んでしまいました。
コンパイラー言語ならば、絶対にコンパイルエラーになるから、こういったポカミスはすぐに分かるのだけれど、CSSの場合は、実行時(ブラウザ起動時)にもエラーになってくれないので、間違いに気が付かなくて、かなりの時間を無駄にしてしまいました。

いつもいつもこんなミスばかりしていては、時間がいくら有っても足りませんね。(^^;
  
Posted by gushwell at 21:29Comments(0)TrackBack(0)