C#を半年やってみて

始めました,つってから半年(blogのトップページが白紙になったのに気づいて書くことに)。

そろそろ見えてきたものがあるのかなと思いつつある今日この頃。

C#(というか.NET)じゃなかったら,そもそもやれる気がしないなぁという部分(.NET Remoting秀逸です)と,あとちょっと何とかして欲しいよねって部分と両方。

で,最近の口癖は「テンプレート欲しい」「スタックにオブジェクト作らせてくれ」の2つ。なんかグチがちょっと出ちゃうのね。

1つめ。
テンプレートがないんで,コンテナからオブジェクトを取り出したりすると,どうしてもキャストの嵐になっちゃう。とにかくいま書いてるコードはキャストが多い。で,そのせいで静的な型付言語というメリットがかなり殺されてて,実行時にならないと分かんないキャストミスが結構発生する。1回実行すればOKとか思うでしょ。そうじゃないんだよね。入力も確実にチェックしないと,途中,コンテナに何が入るかわからんという状態。コンパイラにチェックさせて来た身としては結構ツライ。

あと,気が付くとコピペしたようなコードが大量に増える。そんでもって,そろそろ直さなきゃって感じで,おおもとのクラスを見て,ユーティリティ系のメソッドを見て,インターフェイスを抽出して,って。おい,インターフェイスって。いや,インターフェイスって考え方はいいんだけど,つらい。
C++かObjective-Cならこんな作業要らんのにって。マジで。

で(Objective-Cを多少かじったせいなのか),今度は「object型はObjective-CのNSObjectみたいにどんなメソッドでも受け付けてくれる」ってふと勘違いして,コンパイルエラー。なんか愕然とするね。どうしてもキャストせなあかんのんか,キャストせな…って。

ワタシはC++育ちなので(かつ部署全体がC++系で,Java系がほとんどいないという,割と珍しい部署なので),Javaの人がどうやってこのキャストの嵐をやっつけてるのか非常に興味がある。そういう意味では今でもCだけでやれている人たちにも興味がある。

で,もう1つの「スタックにオブジェクト」ってのは,どっちかというとコンストラクタ・デストラクタとの組み合わせの問題かも。要はリソースの解放をスコープ抜けるときに自動でやってほしいってことなんだけど。

C#にはtry/catch以外にfinallyってのがあるので(Javaにもある?),それ使えばいいって話だけど,例えば3つのリソースを確保するコードを書くとすると,1つ確保するごとにtryブロックにしていく必要があって,どうしてもこの場合は3段ネストしなくちゃダメ。まあ,そんな感じでリソースを確保するごとに(?)どんどんネストが深くなっていく。C++はその点非常に楽チン。

ってゆっても,JavaやC#は,Objective-Cよりは例外を扱いやすい…てゆうか,ライブラリが例外を意識しているかどうか,という点で,かなり差があるわけで。

C++は標準ライブラリが(C#/Javaに比べて)へっぽこピーなんで,ある意味標準ライブラリを無視できる(すみません)し,Objective-Cは実装系が少ないこともあって,メジャーなのはNeXT Step系の(いまや)Cocoaしかなくて,それってば例外をあんまり意識してないし…。

言語とか標準ライブラリの生まれた時点で例外が設計されているかどうかってのは非常に影響が大きい。
JavaもC#(というかCLR)もその点では非常に恵まれている。

…はずなんだけど,.NETの例外クラスは,ひとことで言うと「ひどい」。
たぶん.NETで一番使えない部分は例外クラスの設計だと思う,いや,てゆうか設計されてないもん。適当にthrowしてるだけやんなあ…。

(ちなみに,一番ひどいのは.NET Remoting(JavaでいうRMI?)がリモートサーバで発生したすべての例外をキャッチしてTargetInvocationExceptionをなげること(とはいえ,一番かどうかは人それぞれだと思うけど)。そりゃないぜ,何のための例外だよ?)

…って,まあ,グチはあるものの,.NETというかCLRというか,その辺を含めて,C#って結構良くできてると思う。
side-by-side実行はぜひJavaに取り入れて欲しい。Oracle 9i入れると旅費精算システムが動かなくなるって何なんだよ…って,個人的なグチで済みません。

ただ,もし,仕事じゃなくて個人的に使うのなら?,ってことであれば,もしかしたらmanaged C++を選んでたかも。
やっぱりC++って,better Cっていっていいのか,テンプレートとコンストラクタ・デストラクタだけで,十分魅力ある。.NETでコンストラクタ・デストラクタとか使いたいもの。ArrayListやHashtableじゃなくて,vectorとか使いたいもの(mapは確かにHashtableとは比較しにくいけど)。

なんてゆうか,(C/C++的な)生メモリオブジェクトと(Java/.NET的な)ガーベージコレクション対象オブジェクトと(Objective-CとかCOM的な)参照カウンタオブジェクトとを明示的に使い分けられて,スタックにもオブジェクトを作れて,テンプレートもあって,かつ,クラスのメソッドを静的(仮想関数テーブル経由)にも動的(キャッシュテーブル経由)にも呼び出せるとかって言語があったら,飛びついちゃう。でもって,インタプリタとコンパイラの両方あったりなんかした日には!

ふと,インタプリタは無理にしても,それ以外の機能って,プリプロセッサ的な言語を作ればObjective-C++のソースとして食わせられるコードを吐くぐらいはできそうな気がするな,と思った。

というか寝ろよ>自分