Find Usages Advancedでジェネリックな基底クラスのメソッドのUsageを特定の派生クラス分だけ検索する

RiderのFind Usages Advancedを使って、ジェネリックな基底クラスに定義されたメソッドのUsageを特定の派生クラス分だけ検索する方法です。

Rider2026.2.1

やりたいこと

以下のような、ジェネリックな基底クラスに共通処理をまとめたクラス群があるとします。

using System.Threading.Tasks;

namespace Sample
{
    public abstract class UseCaseBase<TPayload, TResult>
    {
        public async Task<TResult> ExecuteAsync(TPayload payload)
        {
            // ログ出力や例外ハンドリングなどの共通処理
            return await ExecuteCoreAsync(payload);
        }

        protected abstract Task<TResult> ExecuteCoreAsync(TPayload payload);
    }
}

ExecuteAsync は基底クラスにしか定義されていません。
派生クラスが実装するのは ExecuteCoreAsync の方で、ExecuteAsync はオーバーライドしません。

public sealed class LoginUseCase : UseCaseBase<LoginPayload, LoginResult>
{
    protected override Task<LoginResult> ExecuteCoreAsync(LoginPayload payload)
    {
        // ログイン処理
        return Task.FromResult(new LoginResult());
    }
}

public sealed class PurchaseUseCase : UseCaseBase<PurchasePayload, PurchaseResult>
{
    protected override Task<PurchaseResult> ExecuteCoreAsync(PurchasePayload payload)
    {
        // 購入処理
        return Task.FromResult(new PurchaseResult());
    }
}

呼び出し側は、派生クラスの型のまま ExecuteAsync を呼びます。

public sealed class TitlePresenter
{
    private readonly LoginUseCase _loginUseCase;

    public TitlePresenter(LoginUseCase loginUseCase)
    {
        _loginUseCase = loginUseCase;
    }

    public async Task OnLoginButtonClickedAsync()
    {
        var result = await _loginUseCase.ExecuteAsync(new LoginPayload());
    }
}

ここで「LoginUseCaseExecuteAsync がどこから呼ばれているか」呼ばれている箇所を全て調べたいとします。
しかし LoginUseCase には ExecuteAsync の宣言がないので、宣言に対して Find Usages を実行することができません。

呼び出し箇所や基底クラスの宣言に対して Find Usages を実行することはできますが、いずれも基底クラスの ExecuteAsync に対する検索になります。
したがって PurchaseUseCase など、他の派生クラスからの呼び出しもすべて結果に含まれてしまいます。

解決方法

Find Usages Advanced を使うと、検索対象のメソッドを選び直すことができます。

まず、対象の派生クラスの ExecuteAsync を実際に呼び出している箇所にキャレットを置いて右クリックし、Find Usages Advanced を選択します。

Find Usages Advanced

すると Search Properties ダイアログが開きます。
このダイアログの Search 欄には検索対象のメソッドの候補が並ぶので、型引数が TPayload TResult のままになっているもの(ジェネリックな基底クラスのメソッド)ではなく、LoginPayload LoginResult に置き換わっているものを選択します。

Search Properties

あとは Find を実行することで、LoginUseCase 経由の呼び出しだけを結果に表示することができます。

参考

www.jetbrains.com