C# は Microsoft が開発したマルチパラダイムなプログラミング言語です。共通言語ランタイム (CLR) が解釈する共通中間言語 (CLI) にコンパイルされて実行されます。プログラムを実行するためには CLR が必要になるので、Windows 以外の環境では動作しないと思われる方がいるかもしれませんが、実はそうではありません。C# や CLI は Ecma や ISO によって標準化されており、JIS 規格にも採用されています。
C# の開発・実行環境には Microsoft が開発したオリジナルの .NET Framework と、オープンソースプロジェクトの .NET Core や Xamarin / Mono がありますが、それらは .NET に統合されることになりました。.NET はオープンソースで、Windows, Mac OS, Linux などマルチプラットフォームで動作します。最新版 (2022 年 2 月 時点) は 2021 年 11 月にリリースされた .NET 6 になります。.NET 6 は LTS (long-term support) なので、今後は .NET 6 へ移行するユーザーも増えていくのではないでしょうか。
C# でプログラムを作る場合、.NET SDK をインストールすれば最低限の開発環境が整います。統合開発環境 (Visual Studio など) もありますが、本ページではそれを使わずに、エディタで簡単なプログラムを作りながら、C# の基本を勉強していくことにします。なにぶんにも初心者が作るページなので、勘違いや間違いがあると思います。何かお気づきの点がありましたら、メールでご指摘いただけると助かります。本ページは C# に関する M.Hiroi の「覚え書」にすぎませんが、よろしければお付き合いくださいませ。
.NET SDK は .NET (本家) の Download .NET からダウンロードすることができます。インストールの方法は以下のページに詳しく書かれています。
M.Hiroi は 3. に書かれている スクリプトでのインストール で .NET SDK を Ubuntu 18.04 (WSL) にインストールしました。これはインストール用のシェルスクリプト dotnet-install.sh をダウンロードして、シェル (bash) で実行するだけです。.NET SDK は ~/.dotnet に展開されるので、そこにパスを通すことと、環境変数 DOTNET_ROOT にセットすることをお忘れなく。以下のコマンドを .bashrc などに記述しておくといいでしょう。
export PATH=$HOME/.dotnet:$PATH export DOTNET_ROOT=$HOME/.dotnet
.NET SDK でプログラムを作る場合、dotnet というコマンドラインツール (CLI) を使います。たとえば、コンソールアプリケーションを作成する場合、プログラムを作成するディレクトリ (プロジェクト) で次のコマンドを実行します。
dotnet new console [-o name]
dotnet new はプロジェクトを初期化するコマンドです。作成するプログラムの種類 (C# / F# / VB) はオプション -lang で指定することができます。省略した場合は C# になります。これでカレントディレクトリにプログラム (Program.cs) と、プロジェクトに必要なデータが生成されます。ソースファイルの拡張子には cs が使用されます。
また、オプション -o (--output) で作成するプロジェクトを指定することもできます。たとえば、-o hello とするとカレントディレクトリにサブディレクトリ hello が作られて、そこにプロジェクトが生成されます。
プログラムは次のコマンドで実行することができます。
dotnet run [--project name]
オプション --project で実行するプロジェクトを指定します。省略した場合、カレントディレクトリのプロジェクトが実行されます。
簡単な実行例を示しましょう。
$ dotnet new console -o hello テンプレート "コンソール アプリ" が正常に作成されました。 作成後の操作を処理しています... /home/mhiroi/csharp/hello/hello.csproj で ' dotnet restore ' を実行しています... 復元対象のプロジェクトを決定しています... /home/mhiroi/csharp/hello/hello.csproj を復元しました (118 ms)。 正常に復元されました。 $ ls hello Program.cs hello.csproj obj $ cat hello/Program.cs // See https://aka.ms/new-console-template for more information Console.WriteLine("Hello, World!"); $ dotnet run --project hello Hello, World!
実行形式ファイルは次のコマンドで生成します。
dotnet publish [-c conf] [project]
project を省略するとカレントディレクトリのプロジェクトが対象となります。オプション -c (--configuration) を省略した場合、デフォルト値の Debug が使用され、デバッグ用の実行形式ファイルが生成されます。Release を指定すると、リリース用の実行形式ファイルが生成されます。
オプション -c は dotnet run でも使用することができます。なお、実行形式ファイルを出力するディレクトリはオプション -o (--output) で指定することができます。
簡単な実行例を示しましょう。
$ dotnet publish hello .NET 向け Microsoft (R) Build Engine バージョン 17.0.0+c9eb9dd64 Copyright (C) Microsoft Corporation.All rights reserved. 復元対象のプロジェクトを決定しています... 復元対象のすべてのプロジェクトは最新です。 hello -> /home/mhiroi/csharp/hello/bin/Debug/net6.0/hello.dll hello -> /home/mhiroi/csharp/hello/bin/Debug/net6.0/publish/ $ cd bin/Debug/net6.0/publish/ $ ls hello hello.deps.json hello.dll hello.pdb hello.runtimeconfig.json $ ./hello Hello, World! $ dotnet hello.dll Hello, World!
$ dotnet publish -c Release hello .NET 向け Microsoft (R) Build Engine バージョン 17.0.0+c9eb9dd64 Copyright (C) Microsoft Corporation.All rights reserved. 復元対象のプロジェクトを決定しています... 復元対象のすべてのプロジェクトは最新です。 hello -> /home/mhiroi/csharp/hello/bin/Release/net6.0/hello.dll hello -> /home/mhiroi/csharp/hello/bin/Release/net6.0/publish/ $ cd bin/Release/net6.0/publish/ $ ls hello hello.deps.json hello.dll hello.pdb hello.runtimeconfig.json $ ./hello Hello, World! $ dotnet hello.dll Hello, World!
実行形式ファイルの名前は、デフォルトでプロジェクト名と同じになります。プログラムの実行は ./hello のように実行形式ファイルを直接実行するだけではなく、dotnet hello.dll のように dotnet に dll ファイルを渡すことでもできます。
C# を学習する場合、Lisp / Scheme, Python, F# などのような対話モード (REPL) があると便利です。実は C# にも対話モードを実現するためのツール dotnet-script があります。
dotnet-script は次のコマンドでインストールすることができます。
dotnet tool install -g dotnet-script
dotnet-script は ~/.dotnet/tools/ にインストールされるので、そこにパスを通しておいてください。次のコマンドを .bashrc などに記述しておくといいでしょう。
export PATH=$HOME/.dotnet/tools:$PATH
dotnet-script はスクリプト言語のようにプログラム (ソースファイル) を実行します。ソースファイルの拡張子には csx が使われます。引数なしで実行すると対話モードになります。
$ cat hello.csx Console.WriteLine("Hello world!") $ dotnet script hello.csx Hello world! $ dotnet script > 1 + 2 3 > #exit
dotnet script と dotnet-script のどちらでも実行することができます。終了するときは #exit と入力してください。詳しい説明は dotnet-script の README をお読みくださいませ。
さて、肝心な C# の実行速度ですが、いつものように「たらいまわし関数」を使って調べてみました。
リスト : たらいまわし関数 (tak/Program.cs) using System; class Tak { static int tak(int x, int y, int z) { if (x <= y) return z; return tak(tak(x - 1, y, z), tak(y - 1, z, x), tak(z - 1, x, y)); } static void Main() { DateTime s = DateTime.Now; Console.WriteLine("{0}", tak(22, 11, 0)); DateTime e = DateTime.Now; Console.WriteLine("{0}", e - s); } }
それでは実行結果を示します。tak(22, 11, 0) を計算しました。他のプログラミング言語との比較を下表に示します。
$ dotnet publish -o exec -c Release .NET 向け Microsoft (R) Build Engine バージョン 17.0.0+c9eb9dd64 Copyright (C) Microsoft Corporation.All rights reserved. 復元対象のプロジェクトを決定しています... 復元対象のすべてのプロジェクトは最新です。 tak -> /home/mhiroi/csharp/tak/bin/Release/net6.0/tak.dll tak -> /home/mhiroi/csharp/tak/exec/ $ cd exec $ ls tak tak.deps.json tak.dll tak.pdb tak.runtimeconfig.json $ ./tak 11 00:00:01.8498949
処理系 | 秒 |
---|---|
SBCL (ver 1.4.5) | 6.38 |
LuaJIT (var 2.1.0-β) | 4.02 |
SML/NJ (ver 110.98) | 2.66 |
GHC (ver 8.8.4) | 1.96 |
Julia (ver 1.6.4) | 1.95 |
C# (.NET 6) | 1.85 |
SBCL (最適化) | 1.57 |
GCC -O2 (ver 7.4.0) | 1.23 |
Go 言語(ver 1.17.4) | 1.21 |
Scala (ver 2.13.5) | 1.07 |
ocamlopt (ver 4.05.0) | 0.97 |
Java (ver 11.0.10) | 0.95 |
C# はネイティブコードにコンパイルするプログラミング言語に匹敵する結果になりました。この結果には M.Hiroi も大変驚きました。C# (.NET) の JIT コンパイラはとても優秀なようです。興味のある方はいろいろ試してみてください。
『お気楽C#プログラミング超入門』の著作権は筆者「広井誠 (Makoto Hiroi)」が保持します。無断使用や無断転載は禁止いたします。『お気楽C#プログラミング超入門』で作成したプログラムはフリーソフトウェアとします。ご自由にお使いください。プログラムの改造や配布もご自由にどうぞ。その際は出典を明記してくださるようお願いいたします。
ただし、ドキュメントの内容とプログラムは無保証であり、利用したことにより生じた損害について、作者「広井誠 (Makoto Hiroi)」 は一切の責任を負いません。また、これらのプログラムを販売することで利益を得るといった商行為は禁止いたします。