あなたはあなた自身の質問に答えました。クラス外では意味のないヘルパー クラスが必要な場合は、ネストされたクラスを使用します。特に、ネストされたクラスが外部クラスのプライベート実装の詳細を利用できる場合。
ネストされたクラスが役に立たないというあなたの主張は、プライベート メソッドが役に立たないという主張でもあります。プライベート メソッドはクラスの外で役立つ可能性があるため、内部にする必要があります。内部メソッドはアセンブリの外で役立つ場合があるため、公開します。したがって、すべてのメソッドは公開する必要があります。それが悪い議論だと思うなら、メソッドの代わりにクラスに対して同じ議論をすることの違いは何ですか?
クラスの外では意味をなさないヘルパーに機能をカプセル化する必要があり、外部クラスのプライベート実装の詳細を使用できることがよくあるため、常にネストされたクラスを作成します。たとえば、私はコンパイラを書きます。私は最近、解析ツリーのセマンティック分析を行うクラス SemanticAnalyzer を作成しました。ネストされたクラスの 1 つが LocalScopeBuilder です。私がそうでないときに、どのような状況でローカルスコープを構築する必要がありますか解析木のセマンティクスを分析しますか? 一度もない。そのクラスは、完全にセマンティック アナライザーの実装の詳細です。クラス外では役に立たない NullableArithmeticAnalyzer や OverloadResolutionAnalyzer などの名前を持つネストされたクラスをさらに追加する予定ですが、言語のルールをそれらの特定のクラスにカプセル化したいと考えています。
また、ネストされたクラスを使用して、イテレータやコンパレータなどを構築します。これは、クラスの外では意味がなく、よく知られているインターフェイスを介して公開されます。
私が非常に頻繁に使用するパターンは、外側のクラスを拡張するネストされたプライベート クラスを持つことです。
abstract public class BankAccount
{
private BankAccount() { }
// Now no one else can extend BankAccount because a derived class
// must be able to call a constructor, but all the constructors are
// private!
private sealed class ChequingAccount : BankAccount { ... }
public static BankAccount MakeChequingAccount() { return new ChequingAccount(); }
private sealed class SavingsAccount : BankAccount { ... }
等々。ネストされたクラスは、ファクトリ パターンで非常にうまく機能します。ここで BankAccount は、さまざまな種類の銀行口座のファクトリであり、そのすべてが BankAccount のプライベート実装の詳細を使用できます。しかし、第三者が BankAccount を拡張した独自の EvilBankAccount 型を作成することはできません。