マイクロソフトは,ECMAに「C#言語仕様書」を提出し,インターネットなどのネット上を流れるオブジェクトに対する標準的な言語仕様を目指しているようです.
C#の暫定版仕様書および7月末に配布されたプレビュー版C#を使用してみたところ,C#はC++の後継というよりも,C++とJ++を統合した新しい言語仕様といえるかもしれません.
表2に,C#のデータタイプ,予約語,演算子,そして参考としてコマンドラインオプションを示します.
ネットワークデータオブジェクトを扱えるように,現在のXMLも含め,C/C++による低レベルなものからWindows DNAやCOM+などのAPI,そしてXMLまでも統合し,ネットワークプログラミングモデルを低レベルで実現することで,高速でコンパクトなオブジェクトを短時間で開発できるようになることでしょう.
● Visual C++とのおもな相違点
Visual C++との違いは,おもにXMLの包合とIndexerの拡張があげられます.
今までOLEDBなどは,MFCのクラスを用いるかCOMインターフェースを用いて記述していましたが,スクリプト型のデータベースプログラミングを用いることで,今までのソフトウェア資産を有効に利用することができます.
Indexerは,配列(Array)型クラスそのものを扱うという定義により,クラスそのものを配列化し,クラスの動的な再利用を進めます.これは,とくに配列データを扱う配列そのものの構造をクラス化し,クラスを従来の配列のように扱うことで,配列の記述がスマートになります.
(1) ガーベジコレクション
Visual C++ 6.0のデバッガで実装されていたメモリを調べる手段をさらに拡張し,ガーベジコレクションとしてメモリの割り当ておよび解放の管理システムが提供されます.これにより手動のメモリ管理がなくなり,実行時や実行後のメモリの状態が安定します.
これは同時に,他のアプリケーションやシステムに悪い影響を与えることを防ぎます.とくに,リソースの破棄を忘れているような場合,システムリソースを食いつぶし,システムが不安定になったり動作不能に陥ることもあります.そうした可能性を少しでも防ぐことができるという点で,開発者にとっては朗報です.
実際,筆者もβ版の作成時などにはデストラクタでメモリの破棄を行う処理を忘れ,デバッガで追跡することがあります.手動できちんと処理することはもちろん大切ですが,システムが,こういったミスを少しでもカバーしてくれるのは,たいへんありがたいことです.
(2) 変数がシステムによって自動的に初期化される
デバッガでプログラムの動作を追っているとわかりますが,未初期化データ領域でポインタを参照すると,多くの場合には参照エラーが発生し,中断が起こります.偶然,そのようなことが起こらなかった場合でも,そのポインタが有効でないのは明らかです.にもかかわらず,未初期化と初期化済みの区別がつかず,コンストラクタ内などで手動で初期化をするようなことが行われているのではないでしょうか.
C#では,システムが初期化動作を行うので,未初期化かどうかの検査が正確に行われるようになります.
また,C++とは異なり,クラス内での変数宣言時に初期値を指定することで,コンストラクタ内部で行っていた特定値による初期化を,宣言と同時に行うことができます.
(3) ソースレベルでのバージョン管理
Visual Source Safeはファイル管理による管理ですが,C#にはソースコードのバージョンを管理するための解決策が用意されています.
たとえば,メソッドのオーバライドで,C++やJ++で行われてきたような暗黙的な定義ではなく,明示的な宣言によるものに変更することで,リビジョンや構造を変更したため不定になるようなことを防ぎ,明示的にメソッドのオーバライドの定義を行うことで,継承元のメソッドの変更による影響をあらかじめ考慮して設計ができます.
(4) Windows APIなどのネイティブコードの呼び出し
必要な場合には,あらゆるネイティブAPIのコールを可能にする機能が実装されています.
リスト1に,WindowsAPIのフォント操作関数のCreateFontIndirectをDLLからインポート定義して,C#から呼び出すことで表示フォントを変更する例を示します.
すでに実装されているネイティブコードをC#から直接呼び出すことができるので,これまでのソフトウェア資産が無駄になるようなことはありません.
〔リスト1〕Windows APIの呼び出し
|
using System; using System.Runtime.InteropServices; class C { [DllImport("gdi32.dll", CharSet=CharSet.Auto)] public static extern int CreateFontIndirect( [in, MarshalAs(UnmanagedType.LPStruct)] LOGFONT lplf // characteristics ); public static void Main() { LOGFONT lf = new LOGFONT(); lf.lfHeight = 9; lf.lfFaceName = "Arial"; int i = CreateFontIndirect(lf); Console.WriteLine(int.Format(i, "X")); } } |
(5) ネイティブポインタ使用制限の許可
C#では,特別にマークされたコードブロック内でのみポインタを利用できます.C/C++では,手動メモリ管理やポインタの算術演算などを使用することで,システムレベルの操作が必要なデバイスドライバの開発などが行われてきました.しかし,C#ではポインタが制限されることで,こういった用途には若干不向き,かつコードの再利用に制限が加えられることになると思います.
それにもまして,メモリ管理機構などが重要になるような場合は,この制限によって特定のプログラムブロックだけをデバッグしたいような場合に威力を発揮すると思います.
(6) C#におけるATL+
プロジェクトでATL+を選択するとワークフレームが自動的に生成されます.
適切なプログラミングモデルを選ぶことで,Webアプリケーションやサーバコンポーネントなどの開発が短時間で可能になります.
ATL+では,ATL Serverと連携することにより,ATLのライブラリ化や再利用・再開発などを行うことができます.
● C#とC++の実際のコーディングの違い
似ているとはいっても,C#とC++は仕様が異なります.C++では,Cで書かれたコードは拡張子が違うだけで,多くのコードをそのまま再利用できましたが,C#では単純に拡張子を変えるだけでは再利用ができなくなっています.リスト2に,典型的な例を示します.また,図7に,リスト2のファイルを開いた際の画面を示します.
〔リスト2〕C#における参照型
|
namespace Project4 { using System; /// <summary> /// Summary description for Class1. /// </summary> public class Class1 { public int Value = 0; } public class Class2 { public static int Main(string[] args) { int v1 = 0; int v2 = 0; v2 = 123; Class1 r1 = new Class1(); Class1 r2 = r1; r2.Value= 123; Console.WriteLine("Values: {0},{1} ",v1,v2); Console.WriteLine("Values: {0},{1} " ,r1.Value,r2.Value); return 0; } } } |
〔図7〕リスト2のファイルを開いた画面
|
![]() |
リスト2の出力結果は次のようになります.
0,123
123,123
ここで気になるのは,
Class1 r1 = new Class1();
Class1 r2 = r1;
の部分で,C#では参照型ということになります.これをC++で表現すると次のような表現になります.
Class1 *r1 = new Class1();
Class1 *r2 = *r1;
実際,C#コンパイラに,
Class1 *r1 = new Class1();
のコードをコンパイルさせようとすると,標準の状態ではポインタを利用できないのでコンパイルエラーになります.
ソースコードレベルでC/C++からC#への移行が難しいということは,多くのプログラマがC#を新しい言語仕様として最初から学ばなければならないということです.
● XMLからC#のクラスを利用する
C#は,.NETを基本にしているため,XMLからC#クラスを呼び出すこともできます.これにより,XMLによるネットワーキングは,かなり強力なものになることでしょう.さらに,ASP+やSOAPなどのコンポーネントとの連携をC#で細かく定義することで,強力なWebアプリケーションをより簡単に記述できるようになります.
そのほか,マイクロソフトからXMLをVisual Basicのクラスコードに変換するツールが配布されているので,これをC#の利用に役立てるといった工夫ができそうです.今後,XMLからC#への変換ツールがサポートされると相互開発ができて助かると思います.
● C#の使用感
今回,C#のプレビュー版をテストしてみて,C#はC++よりもJ++やPASCALに近いのではないかと感じました.たしかに構文などの多くはC++なのですが,配列の操作やインデックスなど多くの点で,C++にJ++とPASCALを合わせ持った言語ではないかと思いました.
そのため,C++を専門にしてきた人が,C#を使う際に混乱してしまう可能性もあります.とくに,ポインタなどを頻繁に使用しているプログラマが,表記の違いから実変数なのか参照変数なのかを誤って記述し,コンパイルする段階まで気付かないといったこともありそうです.
そうしたトラブルを避けるためにインテリセンスなどの機能が備わっていますが,今回のバージョンは,テストプログラムを作成したり,デバッグを行うにはまだまだ情報不足の感がぬぐえません.今後の開発に期待したいと思います.
公開情報やサンプルからC#の基本を理解するために配布されたものなので,実際の運用の問題を語るようになるまでには時間がかかりそうです.
表3に,現在入手できるおもな資料の参照先を示します.
〔表3〕おもな資料の参照先 |
● C#の今後の展開予測
C#の重要性を考えると,現段階でマイクロソフトから公開されている資料はあまりに少ないといわざるをえません.C#がユーザーの手元に届くのは,早くともVisual Studio 7.0のリリース以後ということになります.
ちなみに,本年4月17日にマイクロソフトが行った発表の中にはC#という記述はなく,Visual Studio 7.0 with Visual C++となっています.そうしたことから,Visual Studio 7.0が配布された後にC#言語の一般開発者向けβテストが開始され,その後に統合されていくという可能性も残されています.
実際,C#をVisual C++の後継にするという表記は今現在では見当たりません.そのため,C#がリリースされる時期の予測はかなり困難です.βバージョンが発表された際には,また改めて検証を行いたいと思いっています.
〔図8〕C#の紹介とオーバービュー |
〔図9〕Microsoft .NET |
おわりに
マイクロソフトの.NET構想,そしてC#について見てきましたが,C/C++の将来はどうなるのでしょうか? このままCがC++に移行したときのように食われてしまうのでしょうか?
次のVisual Sudioでは搭載言語としてC++が入っていますが,J++はC#へと吸収されてしまうような感じです.
たしかに,Visual C++は,デバイスドライバやカーネル部分の開発になくてはならないツールです.このことに異論の余地はないでしょう.では,C#はどのような位置づけと考えるべきなのでしょうか?
C#は,現在のC/C++をすぐに置き換えるようなものではなく,むしろネットワークオブジェクト,たとえばATL ServerやASP+コンポーネントの設計に向いているのだと思われます.
C#の言語がC++を継承しているとはいっても抽象化が進んでおり,ファイルのインクルードを含めてかなりシンプルになってきています.したがって,徐々に移行することは十分に考えられますが,いきなりということはないでしょう.
プロローグ 次のVisual Studio .NETの実行モデル .NET IL(Intermeditate Language) C#について C#の概要 |
Copyright 2000 広畑 由紀夫