【C#】Visual Studio で GitHub Copilot に複数のファイルやコードを認識させる方法

# 複数ファイルやコードを認識させ Copilot を有効に使う

2024年3月ごろから 『Visual Studio + GitHub Copilot』で色々やっています。
今回は GitHub Copilot で複数ファイルやコードを認識させる方法と
その使用例について執筆したいと思います。

## 主な対象読者

Visual Studio で GitHub Copilt をほとんど使ったことがない方や
これから使い始める人向けの内容です。

記事の要約は
『Copilot プロンプト送信時に # を付けて複数のファイルやコードを認識させる』
という内容のなので Copilot の使い方における基本になります。

しかし、これを知っているかどうかで Copilot を活用できる幅が大きく変わるので
使い始める前に、頭の片隅に覚えていると、きっと役に立ちます。

## 動作環境

記事執筆時 2024/03/20 時点での環境です。以下の通りです。

```
IDE: Visual Studio Community 2022 - Version 17.9.3
言語: C# 
インストール済み拡張機能: GitHub Copilot - v1.156.0.0
```

GitHub の個人リポジトリを弄りながら検証したため、エディションは Community です。
検証環境は個人PCであり、勤め先プロジェクトの環境ではありません。

GitHub Copilot が動作する環境要件は、以下の通りです。

```:GitHub Copilot 動作要件
GitHub Copilot には Visual Studio 2022 17.5.5 以降が必要です。
Visual Studio 2022 バージョン 17.4.4 ～ 17.5.4 の場合は、拡張機能バージョン1.84.0.1を使用します。
```

## 課題となったこと－アクティブコード以外は認識できない

今回、私が作業していて課題となった事項について、説明します。
以下のようなコードがあったとします。

```C#:EntityBase.cs
public abstract class EntityBase<T> : IUpdateInfo, IDeleteInfo
{
    // コードの実装
}
```

``EntityBase<T>`` に ``IUpdateInfo`` と ``IDeleteInfo`` のインターフェースが実装されています。
（インターフェースのコード内容は、重要ではないため、省略します）
これに対して GitHub Copilot には
+ ``IUpdateInfo`` と ``IDeleteInfo`` の内容を理解してほしい
+ ``IUpdateInfo`` と ``IDeleteInfo`` のインターフェース実装をサポートしてほしい

以上のような動作を期待していました。

しかし、これに対する GitHub Copilot の反応は、以下の通りです。

![スクリーンショット 2024-03-20 02-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416365/750c0ae6-fd97-ab73-bf3d-34053d5d018e.png)
![スクリーンショット 2024-03-20 02-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416365/693720e5-683a-548e-f2e9-d379b1ee7bd6.png)

つまり GitHub Copilot は
+ ``EntityBase<T>`` は `EntityBase.cs` のタブがアクティブ(開いている状態)のため理解できる
+ 実装されている ``IUpdateInfo`` と ``IDeleteInfo`` の内容は非アクティブで理解できない

**<font color="orange">…そんなこと言われても、複数ファイルをアクティブなドキュメントにできないよ？？？</font>**

これが今回の課題です。

## 解決策－＃を付けてコード参照を追加する

とても簡単でした。
Copilot にプロンプト送信前する際、左下の ＃ を押して
Copilot に認識してほしいファイルを選択してから、送信します。

![スクリーンショット 2024-03-20 02-03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416365/373216c6-fb23-b9e8-45be-5eb1b70aa264.png)

これによる結果は、以下の通りです。

![スクリーンショット 2024-03-20 02-04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416365/4b78308e-5f61-8fc9-bde1-dd70006d5a8b.png)

``EntityBase<T>`` は正しく認識されています。

課題となった ``IUpdateInfo`` と ``IDeleteInfo`` のインターフェースですが
画像内の黄色枠の通り、その実装内容を正しく認識できました。

複数ファイルを認識させる必要がある場合は、このように
＃ で指定することにより、アクティブな作業コード以外を認識させることができます。

## 使い方や応用など

正直、この複数ファイル認識を知っていればいくらでも応用方法は挙げられますが
一例として、先ほどの ``IUpdateInfo`` と ``IDeleteInfo`` を使用した
コードの自動生成を実行してみます。

画像は先ほどの続きとなり、以下のようなプロンプトと Copilot からの回答です。

![スクリーンショット 2024-03-20 02-05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416365/8875694d-fcc4-1bb5-764a-c838309c901e.png)

``IUpdateInfo`` と ``IDeleteInfo`` を元に ``ICreateInfo`` が作成されました。
（namespace の Ateliers は、私の個人所有ドメイン ateliers.dev が元になっています）

``CreateDateTime``のサマリにミスがありましたが、これは GitHub Copilot の問題ではなく
そもそも私の ``IUpdateInfo`` と ``IDeleteInfo`` のコメントが誤っていたのが原因です。

元が間違っている場合、生成されるコードにも誤りが発生するため、注意です。（私もね）

---

より詳細で複雑な生成をしたい場合は、以下のようなこともできます。

```prompt:GitHub Copilot プロンプト
新しいエンティティ OrderEntity を作成して下さい。

新しいクラスには `EntityBase.cs` の EntityBase<T> クラスを継承して下さい。
エンティティ作成の参考には `EntitySample.cs` と `UserEntity.cs` を参照して下さい。
エンティティ作成のガイドラインは `EntityGenGuidelines.txt` を参照し
コーディング規約は `CodingGuidelines.txt` を参照して下さい。
```
（コードブロック内の `*.cs` と `*.txt` は ＃ による参照を表しています）
これで GitHub Copilot は、以下の5つを参照し `OrderEntity` を新規作成します。

| 参照ファイル | 用途 |
|:-:|:-:|
| `EntityBase.cs` | エンティティに実装する基底クラスを理解する |
| `EntitySample.cs` | エンティティ作成時の共通サンプルを理解する |
| `UserEntity.cs` | 実際に作成されているエンティティの実装を理解する |
| `EntityGenGuidelines.txt` | エンティティ作成のルールを理解する |
| `CodingGuidelines.txt` | コーディング共通のルールを理解する |

細かい指示を出すことで、より精度の高いコードが生成されます。

---

ガイドラインは複数用意しておき Copilot への指示時に組み合わせることで
様々な自動生成パターンにも対応することができます。
ドメイン駆動設計を前提とすると、一例は以下の通りです。

| 組み合わせ | 用途 |
|:-:|:-:|
| `EntityGenGuidelines.txt` <br/> + `CodingGuidelines.txt` |  エンティティ作成パターン |
| `ValueObjectGenGuidelines.txt` <br/> + `CodingGuidelines.txt` | 値オブジェクト生成パターン  |
| `RepositoryGenGuidelines.txt` <br/> + `CodingGuidelines.txt` | リポジトリ生成パターン |

## まとめ

１つのアクティブファイルのみを Copilot で使う場合、必ずどこかで限界が来ます。

逆に、複数ファイルを扱うことができれば、できることは無限大に広がります。

覚えておくことで、作業効率と製造コストが大きく変わり
Copilot の便利さを感じることができるため、ぜひ頭の片隅にでも入れておいてください。