🛠️

VSCodeでC#開発をする方法

2020/09/23に公開

はじめに

C#で開発している多くの方は Visual Studio を利用している場合がほとんどだと思います。
ただ、Mac や Linux、Windows で開発環境を変えずに開発をしたい場合があると思います。
そういった際に Visual Studio Code (以下、VSCode) が非常に便利です。

また最近では GitHub Codespaces (旧Visual Studio Codespaces) などの盛り上がりから、より一層 VSCode の需要は高まるばかりです。

そこで今回は VSCode を利用した C# 開発の方法について簡単に紹介していきたいと思います。

事前条件

以下のソフトウェアは導入されている前提で記事を書いています。
導入していない方は以下のリンクより導入しておいてください。

導入プラグイン

この記事では required となっているプラグインのみを使って紹介していきます。
optional となっているプラグインで気になるものがあったら、導入して使てみてください。

✅C# (required)

インテリセンスシンタックスハイライト定義へ移動 などの開発に必要な一通りの機能を提供してくれるプラグインです。
C#拡張

✅VS Sharper for C# (required)

classファイルinterfaceファイル などを追加したときに namespaceclass interface などの情報を自動で入力してくれるプラグインです。
C# Extensions も似たような機能を有しており、こちらよりも有名ですが、この部分の機能に関してはこちらの方が少しだけ優秀です。
VS Sharper for C#

🔵Auto-Using for C# (optional)

まだ using で指定されていない class を利用したときに自動で using を解決してくれるプラグインです。
必要な方は導入してください。
Auto-Using for C#

🔵C# XML Documentation Comments (optional)

XMLドキュメントコメント の作成を補助してくれるプラグインです。
必要な方は導入してください。

🔵 .NET Core Test Explorer (optional)

テストプロジェクトの実行・管理をいい感じにできるようになるプラグインです。

🔵 Bookmarks (optional)

Visual Studio にもある Bookmark 機能を実現できるようになるプラグインです。

🔵 Todo Tree (optional)

Visual Studio にもある Todo 機能を実現できるようになるプラグインです。

🔵NuGet Package Manager (optional)

NuGetパッケージ の検索・インストールができるようになるプラグインです。
NuGet Package Manager

🔵NuGet Reverse Package Search (optional)

class名などから NuGetパッケージ を逆引き検索できるようになるプラグインです。
NuGet Reverse Package Search

Visual Studio についてる NuGetパッケージ管理 のアレと同じ機能を提供するプラグインです。

🔵C# IL Viewer (optional)

生成される IL を表示してくれるプラグインです。
メタプログラミングをする方や自分が書いたコードの IL が見たい人は導入してください。
C# IL Viewer

開発手順

プロジェクト作成

まずは dotnet コマンドを利用して新規プロジェクトを作成します。

dotnet new console -o "SampleConsole"
code SampleConsole

実行すると VSCode が起動して、右下あたりに以下のようなメッセージが表示されると思いますので Yes を選択します。
そうすることによって F5 で Build & Run させることができるようになります。

プログラムの実行

Build & Run

F5 キーを押下することで Build & Run が実行されます。
すると以下のように "Hello, World!" が表示されると思います。

デバッグ実行

また、特定の行で F9 を押下することで Break point を設定・解除することも可能です。
今回は Console.WriteLine("Hello, World!") の行に設定してみます。

設定が正常にできると、以下のように行番号の左側に赤点が付加されます。

再度 F5 を押下すると Break point で実行が一時的に止まります。
また、左のカラムに変数の情報や Call stack の情報が表示されます。

一時停止した状態で F10 を押下することで処理を 1行 進めることができます。

F11 の場合はさらに呼び出し先のメソッドの処理内容へ進むことも可能です(後述)。
このように F10F11 のように1行ずつ処理を進めることを ステップ実行 などともいうので覚えておくとよいかもしれません。

F5 を押下することで処理を通常通り続けることができます。

F11 (Step Into) の場合の動作を確認してみる

Program.cs を以下のように修正して、一度目の Console.WriteLine() に Break point を設定します。

using System;

namespace SampleConsole
{
    class Program
    {
        static void Swap(ref int l, ref int r)
        {
            var tmp = l;
            l = r;
            r = tmp;
        }

        static void Main(string[] args)
        {
            int l = 1, r = -1;
            Console.WriteLine($"left= {l}, right= {r}"); // <- ここに Break point
            Swap(ref l, ref r);
            Console.WriteLine($"left= {l}, right= {r}");
        }
    }
}

F5 を押下し、Break point で停止したところで、まずは F102度 押下してみてください。
Swap() の処理内部に入らず2度目の ConsoleWriteLine() の行まで来たと思います。

次は F11 で同様のことをしてみてください。
すると次のように Swap() の処理内部へ進んだと思います。

これが F10F11 とのステップ実行の差です。
覚えておくとデバッグが楽になるので覚えておきましょう。

Break point に条件をつける

for文などで、特定の値の場合にのみ処理を一時停止させたい場合があります。
そういった場合には Break point に条件を付けることが可能です。

まずは Program.cs を次のように変更してください。

using System;

namespace SampleConsole
{
    class Program
    {
        static void Main(string[] args)
        {
            for (int i = 0; i < 10; i++)
                Console.WriteLine($"i= {i}");    // <- ここに Break point
        }
    }
}

ここで、i が偶数の場合のみ 一時停止したいとします。
その場合、赤点のところで右クリックをして、Edit Breakpoint... をクリックします。

すると条件を記述するためのエディタが表示されるので、そこに条件を記述して Enter を押下します。
ここの条件式には if文 などと同じように普通に条件式を書くことができます

それでは実際に F5 を押下し、実行してみてください。
ここで注目して欲しいのは、i の値です。
一時停止するたびに F5 を押下して、i の値の変化を見てみてください。

i の値が偶数の場合にのみ一時停止していることがわかると思います。
このように Break point に条件を付与することで、特定条件の場合にのみ一時停止させることが可能となります。

標準入力対応

現在のままでは F5 で実行しても標準入力から値を渡すことができません。
試しに Program.cs を以下のように修正して実行してみてください。

using System;

namespace SampleConsole
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.Write("input--> ");
            var input = Console.ReadLine();
            Console.WriteLine($"result= {input}");
        }
    }
}

すると input--> が表示されず、何を入力しても処理が進まないことがわかります。

これに対応するためには launch.json を修正する必要があります。

以下の箇所を修正してください。

{
   "version": "0.2.0",
   "configurations": [
        {
            "name": ".NET Core Launch (console)",
            "type": "coreclr",
            "request": "launch",
            "preLaunchTask": "build",
            "program": "${workspaceFolder}/bin/Debug/netcoreapp3.1/SampleConsole.dll",
            "args": [],
            "cwd": "${workspaceFolder}",
            "console": "integratedTerminal",        // <- ここを integratedTerminal に変更
            "internalConsoleOptions": "neverOpen",  // <- この設定を新規追加
            "stopAtEntry": false
        },
        {
            "name": ".NET Core Attach",
            "type": "coreclr",
            "request": "attach",
            "processId": "${command:pickProcess}"
        }
    ]
}

修正が完了したら再度実行してみましょう。
すると、以下のように正しく実行できると思います。

基本操作

ファイルの追加

左カラムの EXPLORER の位置で右クリックすることで、class や interface などのファイルを追加することができます。
今回は試しに Person というクラスを追加してみましょう。

  1. Add a New C# Class File を選択

  2. Person と入力

  3. Personクラスにプロパティなどを追加

using System;

namespace SampleConsole
{
    public class Person
    {
        public int Age { get; }
        public string FirstName { get; }
        public string MiddleName { get; }
        public string LastName { get; }
    }
}

フォルダ階層が存在している場合、namespace にその情報が反映された状態でファイルが作成されます。
例えば Finances > Money.cs の場合を見てみます。
すると、以下のように namespace が SampleConsole.Finances となってくれていることがわかります。

定義に移動

開発をしていると class や method の実装に飛びたくなるときがあります。
その場合 F12 を押下することで、定義に移動することができます。

先ほど追加した Personクラス を利用して動作を見てみましょう。
それでは Program.cs を以下のように修正して、Person にカーソルを合わせて F12 を押下してみてください。

using System;

namespace SampleConsole
{
    class Program
    {
        static void Main(string[] args)
        {
            var person = new Person();
        }
    }
}

おわりに

今後も随時更新していこうと思います。

Discussion