以下の内容はhttps://rksoftware.hatenablog.com/entry/2025/05/18/220000より取得しました。


大量のクラスを作る際に GitHub Copilot に手伝ってもらいたかった

このリポジトリのコードに main でないブランチですが、大量のクラスがあります。
github.com

■ 大量のクラス

IServiceCollection の拡張メソッドに対するコードを書いています。この拡張メソッドの定義クラスが本当に多い。そのための自分のリポジトリでも大量のクラス + プロジェクトが生まれています。

見てください。このプロジェクト数を!

■ どんなクラス?

こんな感じのモッククラスです。テスト用の。
メソッドの呼ばれた回数を確認できるようにして、テストで実際に呼べているかどうかをモックで確認するものです。

using System;
using System.Collections.Generic;
using System.Text;

namespace Microsoft.Extensions.AmbientMetadata.Application;

public static class ApplicationMetadataServiceCollectionExtensions
{
    public static List<string> Invoked = new List<string>();

    static object? Add(string name)
    {
        Invoked.Add(name);
        return null;
    }

    public static object? AddApplicationMetadata(this object? services, object? section) => Add("public static object? AddApplicationMetadata(this object? services, object? section)");

    public static object? AddApplicationMetadata(this object? services, Action<object?> configure)=>Add("public static object? AddApplicationMetadata(this object? services, Action<object?> configure)");
}

ただ、今は大量のクラスの定義をもれなく書けるよう、本物のメソッドを「実装に移動」した結果をクラスのファイルに貼っている状態です。

#region アセンブリ Microsoft.Extensions.Compliance.Testing, Version=9.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
// Decompiled with ICSharpCode.Decompiler 8.2.0.7535
#endregion

using System;
using Microsoft.Extensions.Compliance.Redaction;
using Microsoft.Extensions.Compliance.Testing;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Options;
using Microsoft.Shared.Diagnostics;

namespace Microsoft.Extensions.DependencyInjection;

//
// 概要:
//     Extensions that allow registering a fake redactor in the application.
public static class FakeRedactionServiceCollectionExtensions
{
    //
    // 概要:
    //     Registers the fake redactor provider that always returns fake redactor instances.
    //
    //
    // パラメーター:
    //   services:
    //     Container used to register fake redaction classes.
    //
    // 戻り値:
    //     The value of services.
    //
    // 例外:
    //   T:System.ArgumentNullException:
    //     services is null.
    public static IServiceCollection AddFakeRedaction(this IServiceCollection services)
    {
        Microsoft.Shared.Diagnostics.Throw.IfNull(services, "services");
        services.TryAddSingleton<FakeRedactionCollector>();
        services.TryAddSingleton((Func<IServiceProvider, IRedactorProvider>)delegate (IServiceProvider serviceProvider)
        {
            FakeRedactionCollector requiredService = serviceProvider.GetRequiredService<FakeRedactionCollector>();
            FakeRedactorOptions value = serviceProvider.GetRequiredService<IOptions<FakeRedactorOptions>>().Value;
            return new FakeRedactorProvider(value, requiredService);
        });
        return services.AddOptionsWithValidateOnStart<FakeRedactorOptions, FakeRedactorOptionsAutoValidator>().Services.AddOptionsWithValidateOnStart<FakeRedactorOptions, FakeRedactorOptionsCustomValidator>().Services;
    }

    //
    // 概要:
    //     Registers the fake redactor provider that always returns fake redactor instances.
    //
    //
    // パラメーター:
    //   services:
    //     Container used to register fake redaction classes.
    //
    //   configure:
    //     Configures fake redactor.
    //
    // 戻り値:
    //     The value of services.
    //
    // 例外:
    //   T:System.ArgumentNullException:
    //     services or configure> are null.
    public static IServiceCollection AddFakeRedaction(this IServiceCollection services, Action<FakeRedactorOptions> configure)
    {
        Microsoft.Shared.Diagnostics.Throw.IfNull(services, "services");
        Microsoft.Shared.Diagnostics.Throw.IfNull(configure, "configure");
        services.TryAddSingleton<FakeRedactionCollector>();
        services.TryAddSingleton((Func<IServiceProvider, IRedactorProvider>)delegate (IServiceProvider serviceProvider)
        {
            FakeRedactionCollector requiredService = serviceProvider.GetRequiredService<FakeRedactionCollector>();
            FakeRedactorOptions value = serviceProvider.GetRequiredService<IOptions<FakeRedactorOptions>>().Value;
            return new FakeRedactorProvider(value, requiredService);
        });
        return services.AddOptionsWithValidateOnStart<FakeRedactorOptions, FakeRedactorOptionsAutoValidator>().Services.AddOptionsWithValidateOnStart<FakeRedactorOptions, FakeRedactorOptionsCustomValidator>().Configure(configure).Services;
    }
}

このクラスを、前述のコードにしていかなければなりません。大量に。ちなみに書き換え終わったコミットのファイル数見たら 42 ファイルでした。実際多い!

■ 助けて! GitHub Copilot !!

ApplicationMetadataServiceCollectionExtensions クラスを参考に書き換えて

こんな感じで、すでに一度書き終えたクラスを参考に別のクラスを整えてもらうことを試みます。

全然ダメでした。
ApplicationMetadataServiceCollectionExtensions を見ていませね。というわけで @workspace を付けてみます。

ダメでした。ApplicationMetadataServiceCollectionExtensions クラスを見つけられなかったようです。

■ ファイルを添付する

明確に ApplicationMetadataServiceCollectionExtensions クラスを読めるようクラスのファイルを添付してみます。


よさそう!

■ ファイルはたくさん

繰り返してたくさんのファイル、もしかしたらエージェントモードで!?

開いているクラスたちを ApplicationMetadataServiceCollectionExtensions クラスを参考に書き換えて


書き替えたということですが、エディタのコードは変わっていません。どう操作していいかよくわかりませんでした。
ここで悩んでいても進まないので、別の方法も。

■ エディットモード

エディットモードでひとつのファイルづつ。

#region アセンブリ Microsoft.Extensions.Caching.StackExchangeRedis, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60
#endregion

#nullable enable

using Microsoft.Extensions.Caching.StackExchangeRedis;
using System;
using System.Collections.Generic;

namespace Microsoft.Extensions.DependencyInjection;

public static class StackExchangeRedisCacheServiceCollectionExtensions
{
    public static List<string> Invoked = new List<string>();

    static object? Add(string name)
    {
        Invoked.Add(name);
        return null;
    }

    public static object? AddStackExchangeRedisCache(this object? services, object? section)
        => Add("public static object? AddStackExchangeRedisCache(this object? services, object? section)");

    public static object? AddStackExchangeRedisCache(this object? services, Action<object?> configure)
        => Add("public static object? AddStackExchangeRedisCache(this object? services, Action<object?> configure)");
}

いいね!

■ しかし

その後何度かやるも、エディットモードでも同じような結果になることはほとんどなく。

今回は、ここで時間をかけるよりまずはコード補完に頼って頑張って手でやっていくことにしました......。
何百と繰り返すなら、多分プロンプト頑張れば行けそうですが。

やはり GitHub Copilot は CoPilot であって、オートパイロットでなんかいい感じに全部コードが湧き出してくる魔法の壺というわけではありませんね。
魔術師は私。Copilot は魔法の指輪です。




以上の内容はhttps://rksoftware.hatenablog.com/entry/2025/05/18/220000より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14