C# をやることになった
C#.NET をやることになった。ちょっと古い C# 2.0 を使っているので 3.0 の型推論とかが無いのがちょっと残念だけど。
まだ初心者だけど、いまのところのお気に入り点
usingブロック
以下のように書くと、ブロックを抜けるときに、自動で引数に指定した変数の IDisposable#Dispose() メソッドを呼んでくれるというもの。*1
using (StreamReader reader = new StreamReader("file.txt")) { // readerを使った処理... }
上のコードはRubyのこれのようなもの。
File.open("file.txt") do |file| # file を使った処理... end
delegate
Javaのように無名クラスを介さなくても、簡単に関数オブジェクトやクロージャのようなものが作れる。delegate は += で連結することもできる。
class Program { delegate void TextWriterDelegate(TextWriter writer); static void Main(string[] args) { TextWriterDelegate testDelegate = CreateWriteLineDelegate("テスト"); OutputToConsole(testDelegate); // 「テスト」と表示 testDelegate += CreateWriteLineDelegate("テスト2"); OutputToConsole(testDelegate); // 「テスト」「テスト2」と表示 } static TextWriterDelegate CreateWriteLineDelegate(String text) { return delegate(TextWriter writer) { writer.WriteLine(text); }; } static void OutputToConsole(TextWriterDelegate twDelegate) { twDelegate(Console.Out); } }
GenericsがILレベルでサポートされている
JavaのGenericsは単なるシンタックスシュガー・コンパイラのチェック機能で、コンパイル後のクラスファイルに型引数の情報が残らない。なので、たとえば
class Foo<T> { private Class clazz = T.class; }
のようなことはできず、たとえばこんな場合などにちょっとダルいことになる。
C#ではILのレベルでGenericsをサポートしているので、
class Foo<T> { private Type type = typeof(T); }
が可能。ほかにも値型のboxing/unboxingが発生しないなどのメリットがある。
逆にダメな点
(Microsoft製の)標準ライブラリのソースが確認できない。これが最悪。
あとは、コレクション関係のライブラリが貧弱なこと。SortedList を逆順にすることすら こんな手順 が必要って本当なんだろうか……。
*1:Stream などを対象にした場合に Dispose() と Close() が全く同じなのかどうかはドキュメントに書いてない。ただ、確認した限りでは同じらしい。