3.0では、明示的に型を指定することなく、ローカル変数を宣言することができる。123;と書くことができる。「var」というキーワードは「暗黙的に型指定されるローカル変数」を宣言するためのキーワードなので、int型以外の変数を宣言する場合にも使用できる。3.0";と書いてもよい。MyClass();と書くこともできる。このような機能に対しては、過剰な肯定と、過剰な否定という2つの典型的なリアクションがしばしば見られるように思う。Language、軽量プログラミング言語)の信奉者などに見られるものである。彼らは、型をソース・コード上に明示せず、実行時に動的に型を扱うことがよいと主張することが多い。上記のような構文は、型の解決がコンパイル時から実行時に遅延されたかのように見えるために、C#が静的に型付けされた言語から、動的に型付けされた言語に変わったかのように見えることがある。Basic(以下VB)におけるVariant型の悪夢再来と受け止めるタイプである。この件は後で詳しく説明する。3.0をうまく扱えないワナにはまり込むリスクがある。そこでこの件について、詳しく説明してみよう。3.0の「暗黙的に型指定されるローカル変数」を分かりやすく説明するために、それとは明らかに違うVBのVariant型を紹介し、相違点を示すことにする。違うものとの対比を行う方が、特徴が分かりやすく浮かんでくるからである。2.0から6.0までに存在するデータ型で、どのような型の値でも格納できる「魔法の箱」として機能する。変数宣言時に型を省略した場合はこの型になるので、型を一切明示せずにソース・コードを記述することも不可能ではない(明示的な型変換を行うコードを含む可能性はあるが)。Variant型を、(6.0までの)VBらしさを象徴する特徴的な機能と思う技術者も多いのではないかと思う。1.0日本語版がリリースされておらず、Variant型導入前のVBを知らない技術者が大多数と思われるため、その傾向は顕著だろう。1.0時代からVBを使い込んでいたので、違う印象を持っている。1.0とは厳格に型付けされた言語であった。何でも入る「魔法の箱」は存在せず、変数を宣言する際に型を省略すると整数(Integer)型と見なされ、整数は代入できても文字列は代入できない変数だったのである。型はソース・コード上で明示する方がよい、と思っていたので、筆者はこのようなVBの仕様を素直に受け止め、変更される可能性などまったく考えていなかった。2.0がやって来たとき、あらゆる機能が好ましい意味で改良されていたにもかかわらず、Variant型が導入されて型を明示しないプログラミングが可能になったことに驚いた。その当時、これは悪夢そのものであり、Variant型は使うべきではない、と筆者は考えた。2.0唯一の決定的な弱点と思ったのである。ちなみに、何でも入る魔法の型といえば、C#ではobject型がそれに当たる。object型とVariant型は同じではない。object型は参照型であり、値型の値を扱うにはボックス化という手順が必要になる。参照型である以上、メモリの確保と破棄というオーバーヘッドが必ずついて回る。Variant型は整数のような値であっても、オブジェクトへの参照であっても、それをそのまま格納できる。ボックス化やメモリの確保、解放のオーバーヘッドもない。万能の魔法の箱である。Variant型の何が問題なのだろうか。Variant型の悪夢の典型的な例を1つ挙げよう。コメントを多く補ったので、VBの文法を知らなくても読めるだろう。最初の2つの加算では、整数と、文字列を整数化した値を加算して結果としている。そこで、同様の結果を期待して文字列と文字列を加算させると期待は裏切られて、「整数の足し算」ではなく「文字列連結」が行われてしまう。このような結果になる理由はVariant型ではなく+演算子が持つ機能性にある。ここで、Variant型が悪夢を持ち込むのは、原因と結果の因果関係を切り離す効能を持つためである。"2"という式を直接書けば、結果が3ではなく"12"になることは誰でも容易に予測できるだろう。Variant型変数が介在することで、原因と結果の因果関係が見えにくくなり、すぐ原因が推定できない深刻なバグを作り込んでしまうリスクを持つ。このような問題を解決する最も簡単なやり方は、型を明示することである。変数の宣言を以下のように書き換え、整数を示す型名であるIntegerを明示的に指定する。Integerこれで実行結果は以下のようになり、意図どおりとなる。3.0の「暗黙的に型指定されるローカル変数」を見たときに感じたのは、上記のような「Variant型の悪夢」の再来であった。それはまったくの誤解であった。3.0に書き換えてみよう。すると、すぐに重大な問題に直面することになる。b」に相当する、以下の変数宣言がエラーになってコンパイルできないのである。暗黙的に型指定されたローカル変数には複数の宣言子を指定できませんつまり1つの宣言では1つの変数しか宣言できず、かつ、初期化されねばならないわけである。この構文上の制約を受け入れたうえで、C#に書き直してみよう。このコードはコンパイルできない。暗黙的に変換できません。暗黙的に変換できません。暗黙的に変換できません。見てのとおり、Variant型の変数aには整数を入れた後で文字列を入れることが可能だったのに対して、「暗黙的に型指定されるローカル変数」の変数aは、整数で初期化した後で文字列を代入することはできない。それは、実行時ではなくコンパイル時にエラーとなってはじかれてしまうのである。「暗黙的に型指定されるローカル変数」がVariant型と似ているように見えるとしても、それは単なる錯覚にすぎず、両者はまったく異なる機能性を持っているのである。3.0においては発生しない。まとめると以下のようになる。1;」は完全に等価)型はコンパイル時に確定し、コンパイル時にチェックされる。LL信奉者に期待する者が多い「実行時まで型の解釈を遅延する」機能性とはまったく違う。7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。TranslatorはPowerPoint用のアドイン。