C#で開発時、ちょっとしたテストコードをスクリプト言語のようにコンパイルを挟まず実行できる環境を用意しておくと良いと考えています。C#はコンパイルして実行するまでに、そこそこ手間がかかりますし。
ググるとC#インタラクティブ1、csi2という手段も出てきます。
ただし今回は以下の条件から、dotnet-scriptに採用します。
https://github.com/filipw/dotnet-script
- 開発環境はmacOS
- IDEに依存しない
.NET Core 2.1SDKのインストール
本家のマニュアルに従ってdotnet-scriptの環境を構築していきますが、実行させるにあたって**.NET Core 2.1SDK**は必須です。以下のサイトからダウンロードしてインストールしておきます。
https://dotnet.microsoft.com/download/dotnet-core
※C#8.0を使用する場合は.NET Core 3.1SDKをインストールします。ちなみに.NET Core3.1SDKだけではdotnet-scriptは動きません。
dotnet-scriptのインストール
dotnet toolでインストール
プラットフォーム問わず、以下のコマンドでdotnet-scriptをインストールできます。
$ dotnet tool install -g dotnet-script
curlでインストール
macOSの場合は以下のcurlコマンドでもインストールできます。
$ curl -s https://raw.githubusercontent.com/filipw/dotnet-script/master/install/install.sh | bash
# もしパーミッション周りでエラーを吐く場合は以下のコマンドを実行してください
$ curl -s https://raw.githubusercontent.com/filipw/dotnet-script/master/install/install.sh | sudo bash
(補足)エディタはVSCodeを使用
使用するエディタは何でも良いですが、僕はサクッと環境を構築できるVisualStudioCode(以下:VSCode)を使いました。
- MicrosoftのC#
- LeopotamのC# FixFormat
この2つをExtensionsをインストールしておきます。
コード補完が利くようになりShift + Option + F
でソース整形されるようになります。

これで環境構築は完了です。
Hello world!する
$ dotnet script init
initコマンドを実行すると、以下のテンプレートファイルが生成されます。3
├── main.csx
└── omnisharp.json
以下のコマンドを実行するとHello world!
と出力されます。
$ dotnet script main.csx
パスの扱い
指定したパスの扱いについて調査していきます。
以下のファイル構成をサンプルに調査を進めます。
├── Sample1.csx(dotnet-script実行ファイル)
├── test01.txt
└── test02.txt
試しに以下のソースコードを実行してみます。
var files = Directory.GetFiles(".");
foreach(var filePath in files)
{
Console.WriteLine(filePath);
}
以下のログ出力の通り、実行ファイル(Sample.csx)を起点にした相対パスのようです。
./test01.txt
./test02.txt
./Sample1.csx
コマンドライン引数の取得方法
$ dotnet-script Sample1.csx arg1 arg2 arg3
上記のようにコマンドライン引数にarg1, arg2, arg3と3つの値をセットしてスクリプト側で受け取る方法です。
Console.WriteLine(Args[0]);
Console.WriteLine(Args[1]);
Console.WriteLine(Args[2]);
このようにArgs
に詰め込まれているので、上記のようなコードで受け取ることが出来ます。
ちなみにArgsは IList<string>
ですので、要素数を取得したい場合は、Length
ではなくCount
を使用します。
コマンドライン引数が必須のスクリプトの場合、以下のようにArgsがnullになる場合があり、以下のようなエラーが出力されます。
System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
このようなnullチェックを事前に走らせた方が良いでしょう。
if (Args == null && Args.Count <= 0){
// コマンドライン引数はありません
return;
}
ファイルのリネーム処理サンプル
サンプルを1つ作ってみます。
以下は指定ディレクトリ内の、.txtファイル
を.csファイル
にファイルリネームするというものです。
var dirPath = Args[0];
var files = Directory.GetFiles(dirPath, "*.txt");
foreach(var filePath in files)
{
var dirPath = Path.GetDirectoryName(filePath);
var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(filePath);
var newPath = $"{dirPath}/{fileNameWithoutExtension}.cs";
File.Move(filePath, newPath);
}
全ソースはコチラ
以下のように引数にディレクトリパスを指定してdotnet-scriptを実行します。
$ dotnet-script RenameTxt2Cs.csx 任意のフォルダパス(絶対パス or 相対パス)
最後に
dotnet-scriptを使うとC#をインタプリタ型言語のようにライトにC#を実行できるようになります。
本記事では触れていませんがREPLでも動作します。
テストコードを書いてサクッと挙動をチェックする時などに使えますのでC#を扱うエンジニアはdotnet-scriptが動く環境を作っておくと開発効率が上る可能性はあるなと思いました。
トラブルシューティング
.NET Core2.1が未インストールエラー
dotnet-scriptコマンド実行時に以下のエラーが出た場合は**.NET Core2.1が未インストール**です。
インストールすると解決します。
バイナリはコチラからダウンロードできます。
It was not possible to find any compatible framework version
The framework 'Microsoft.NETCore.App', version '2.1.0' was not found.
- The following frameworks were found:
3.1.6 at [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
You can resolve the problem by installing the specified framework and/or SDK.
The specified framework can be found at:
- https://aka.ms/dotnet-core-applaunch?framework=Microsoft.NETCore.App&framework_version=2.1.0&arch=x64&rid=osx.10.15-x64
dotnet script
とdotnet-script
コマンド
dotnet toolでインストールした場合はdotnet script
、curlでインストールした場合はdotnet-script
を使用します。少しハマりました。
環境
- dotnet-script v0.53.0
- macOS 10.15.5
-
C#インタラクティブはVisualStudio依存 ↩
-
csiはMac向けにリリースされていないため、本記事では扱わない(参考:https://www.buildinsider.net/language/csharpscript/01) ↩
-
既にcsxファイルが存在する場合は生成されません ↩