.NET Core 3.0以降のGroupCollectionは、IReadOnlyDictionary<string, Group>インターフェイスも実装しています。 これにしたがって、GroupCollectionをディクショナリとして扱えるほか、グループ名前付きグループKeyValuePair<string, Group>として取得することができます。

上記の結果にも現れているように、IReadOnlyDictionary<string, Group>を介したアクセスの場合、名前なし・名前付きに関わらずグループ化された部分が列挙されます。 また、名前なしのグループでは、グループ番号は文字列のキーとして列挙され、マッチ箇所全体を表すグループとして"0"が常に含まれます。

このほかにもGroupCollectionでIReadOnlyDictionary由来のメソッド・プロパティとして、KeysプロパティContainsKeyメソッドTryGetValueメソッドを使うこともできます。 これらのメソッド・プロパティは、正規表現にマッチしたかどうかで返す値が変わります。 具体的には、ContainsKeyメソッド・TryGetValueメソッドは、正規表現にマッチした場合、かつ正規表現内に指定された名前・番号のグループを含む場合のみtrueを返します。 つまり、特定の名前・番号のグループにマッチしたかどうか表す値を返すのではないため、逆にいえばこのメソッドの戻り値から正規表現全体がマッチしたかどうかを知ることができます。

GroupCollection.TryGetValueメソッドを使って正規表現にマッチした場合にグループ化した箇所を取得する
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;

class Sample {
  static void Main()
  {
    // 整数表現にマッチする正規表現
    // (符号部分を名前'sign'としてグループ化、絶対値部分を名前'number'としてグループ化)
    var pattern = @"(?<sign>\-|\+)?(?<number>[0-9]+)";

    foreach (var text in new[] {"+123", "45", "abc"}) {
      var m = Regex.Match(text, pattern);

      Console.Write($"{text} => {(m.Success ? "match" : "not match")} ");

      // 正規表現にマッチした場合は、グループ'sign'の部分を表示する
      if (m.Groups.TryGetValue("sign", out var sign))
        Console.Write($"sign='{sign.Value}' ");

      // 正規表現にマッチした場合は、グループ'number'の部分を表示する
      if (m.Groups.TryGetValue("number", out var number))
        Console.Write($"number='{number.Value}' ");

      Console.WriteLine();
    }
  }
}
実行結果
+123 => match sign='+' number='123' 
45 => match sign='' number='45' 
abc => not match