きな粉もち.net

.NET関連仕事に携わっています。OSSのソースを読んで気がついたことを中心に呟いたりブログに投稿したりしています。最近はUiPathを使ったRPAも研究中。気軽にフォローやツッコミよろしくおねがいします! Gitはここを使っています https://github.com/kinakomotitti

log4net × FileStream × Using

log4netでは、ファイルの排他制御にLockModelクラスを利用しています。

そのLockModelクラスでは、ファイルの出力操作にFileStreamを使って出力を行います。(LockModelには3つの種類がありますが、どのModelを使ってもFileStreamを利用します。)

 

出力の準備処理の実装がこれです!

f:id:kinakomotitti:20171103235500p:plain

呼び出し元から、File名と、ファイルに上書きするか、追記するかのフラグと、アクセス制御に関するEnumを受け取り、FileStreamを呼び出し元に返す処理を実行します。

 

実装から見てわかる通り、log4netでは、指定されたファイル名から、ディレクトリ名を取り出し、そのディレクトリがなければ生成してくれるようです。

確かに、いつの間にかLogフォルダがbinフォルダに生成されたりしますね!

 

仕様を軽く見たところで、実装面で気になった所を見ていくことにします。

今回特に気になった実装は・・・ここの部分!

 

 

f:id:kinakomotitti:20171104000203p:plain

 

 

・・・ではなく、ここです!

f:id:kinakomotitti:20171104000326p:plain

上記の実装も、IFで実装するより、シンプルにわかりやすく実装されているので、とても参考になりますが、このUsingの使い方は初めてみたので、こちらを見ていくことにしました。

そもそも、usingのメリットは大きく2つあると思います。

 1)usingで宣言した変数を確実にDisposableしてくれる。

 2)Try~Finallyと同じ効果(例外を握りつぶす)

今回の実装では、Usingしている変数は以下のように定義されている抽象クラスのものになるので、2)の目的で利用されているのではないかと考えています。

f:id:kinakomotitti:20171104002726p:plain

IDisposableはそのままではusingで宣言できないので、上記のようにすることでimpersonate(偽装)しているのだと思います。

今までusingしたいけど、IDisposableを継承した変数がなかったときは仕方なくtryを書いていました。

しかし、この実装テクニックがあれば今後はより気軽にUsingを使っていけると思いました!