C#(これは古い日記です)

1年くらい前に3日くらい勉強して、だいたい理解したかな、と思ったものの、それ以降さっぱり使わないで1年たってしまったために、3日程度の知識はさっぱり抜けてしまっていたC#の勉強をもう一度してみた。

まあ、C#C++++を匂わせる名前なものの、C++よりはるかにJavaに近い言語なわけだが、C++Javaをどちらも知ってる人間なら、基本的な部分は1〜2日程度でほとんど理解できる。Javaだけ知ってても同じくらいだと思う。というかC++使いやJava使いが簡単に理解できるように作られているので、まあそれは当然だ。

C#入門(WisdomSoft)辺りをざーっと斜め読みすれば、序盤はJava知ってる人ならほとんど読み飛ばせるので、1日くらいで全部読める。まあこれ全部読んだだけでC#理解しました、とはならないだろうが。

C#がどういった言語かというと、まあ(Java - 1) | (C++ / 2) | α といった感じになる。以下、個人的なC#メモから抜粋。

C++, Java との主な違い

  • 基本的な部分はほとんど Java と同じ
  • ///、/** */ コメントがある(いずれも Java の /** */ と同じ)
  • グローバル変数、グローバル関数がない(Java と同じ)
  • デフォルト引数がない
  • クラス宣言?の末尾に ; は不要(Java と同じ)
  • 文字列の比較が ==, != で正しく行える
  • switch が fall through しない、全ての節で break が必須(あるいは goto でも可)
  • int 等の変数のサイズが決まっている(Java 的)
  • >>> シフトがない(算術シフトのみ)
  • if(!0) のような暗黙の int => bool 変換ができない(Java と同じ)
  • goto が外側のスコープにしか飛べない
  • ラベル付き break, continue はない
  • ref, out で参照渡しができる(ref が C++ の & に相当)
  • ref, out を用いなければ Java と同じ
  • デストラクタ(というかファイナライザ)が微妙(呼び出されるタイミングがわからない、Java と同じ)
  • 代わりに?Dispose() というリソース解放用のメソッドがある
  • 静的コンストラクタというものがある(Java の静的初期化ブロックに相当)
  • 多重継承はできない
  • 継承の構文は C++ に似てるが、public とかは指定できない(class Derived : Base {})
  • 基底クラスへは base キーワードでアクセスする(Java の super に相当)
  • 基底クラスのコンストラクタの初期化構文は C++ に似てる(Derived() : base(/* 引数 */) {})
  • 上記構文でメンバ変数の初期化はできない(と思う)(Java 的)
  • オーバーライド、隠蔽の構文、規則がちょっと違う
  • 継承を禁止するクラスに sealed を付ける(C++ での非ポリモーフィッククラス、Java での final に相当)
  • オーバーライド時、以降のオーバーライドを禁止するメソッドに sealed を付ける(C++ での非 virtual, Java での final に相当)
  • デフォルトのメソッドは C++ と同様、オーバーライドできない(virtual を付ける必要がある)
  • アクセス修飾子に internal というものがある(Java のデフォルトはない、デフォルトは private)
  • クラス型オブジェクトの扱いは Java と同様(スタックに積めない、GC が回収)
  • 構造体がかなり違う(クラスと異なり、スタックに積むことができる、C++ のオブジェクト的、非Java 的)
  • 多次元配列の扱い方が2種類ある(片方は Java と同じ)
  • instanceof は is
  • dynamic_cast は as
  • enum の扱いが違う(Javaenum は知らない)
  • NullPointerException が NullReferenceException である

C++, Java にはない機能

  • @"string" という文字列がある
  • ref, out(参照、出力用ポインタみたいなもの)
  • プロパティ(getter, setter, Java のプロパティとは別物)
  • インデクサ(operator[]() みたいなもの)
  • 可変長引数を扱える(params)
  • readonly(初期化時に一度だけ代入可能な変数(定数))
  • foreach 構文
  • delegate(関数ポインタみたいなもの)
  • イベント
  • typeof 演算子
  • 参照型と値型が相互変換可能
  • 多次元配列(Java の多次元配列とは違う方)
  • Dispose() (リソース解放用メソッド)
  • その他いろいろ

まあ、言語としてみた場合も、実行環境としてみた場合も、ほとんどJavaである。しかし後発言語の強みで、Javaよりは良い。C++と比べたら、まあ優れている部分も多いが、やはりtemplateがないというのは弱い。C#2.0ではGenericsがサポートされるが、おそらくこれはJava5.0のGenericsと同じようなものだと思われる(よく知らないのであくまで想像だが)。Genericsってのはなんちゃってtemplateなので、単純にコレクションに型を付けるって程度のことしかできず、Modern C++ Designに出てくるようなことはできない。まあModern C++ Designのような変態的なtemplateの使用方法がどれだけ実用に足るかと言うのも疑問ではあるが。

C#は.NETなので、Javaと同じようにランタイムライブラリを必要とするが、.NET FrameworkMicrosoftがOSと一緒に配布してくれたりするため、Javaのアプリケーションを一般人に配布するときにJREをインストールしてください、みたいな面倒なことにならないというのがJavaに対する強みか。上で書いたように、Java使いの人ならC#の修得は容易なので、Java VS. C#の構図でJavaが滅んでも別に困ることはないと思います。別にC#が滅んでも困りませんが。まあ個人的にはC#の方が好きです。

などと思っていたら、C++/CLIとかいうものがVS2005で現れるらしい。Managed C++を進化させたもので、評判だけ聞くとかなりいいようだ。まあManaged C++は全然知らないわけですが。C++は好きなのでC#を捨てて乗り換えるかも。