This code is a non-static C# class for rolling a number of dice
I have few tips:

Infinite recursion.
The app would never finish until you call Environment.Exit because you have infinite recursion. The result of the infinite recursion is always StackOveflowException, sooner or later. Take the trigger: if you forced to use Environment.Exit to stop the app, then something went wrong. About correct usage of the recursion: on some level of calling the recursive method must return not make a recursive call again. Then the recursion would finish normally. Btw, you need no recursion here.

Naming
Give all the items: classes, namespaces, variables, fields, etc. names that explains its purpose or containing value. It would make the code maintaneable. Also I use the following standard.
private int _fieldName;

public int PropertyName { get; set; }

public void DoSomething()
{
    int localVariableName = 0;
}

It allows explicitly differ fields and local variables in a code even if I'm reading the code outside of IDE editor.

Incapsulation.
The OOP principle that helps you in development to avoid popular mistakes. What method should I call when I create an instance of RollDice class? All the methods are public. Leave public only that class components which you allow to access outside of the class.

Small tips.
Remove inheritance class RollDice : Program, it does nothing. Let the methods and classes do some single job. (see S in SOLID principles for details).


Here's some alternative implementation of the same to play.
class Program
{
    static void Main(string[] args)
    {
        RollDice dice = new RollDice();
        dice.Run();
        Console.ReadKey();
    }
}

public class RollDice
{
    private const int maxDice = 100;
    private const int minDice = 1;
    private const int maxSides = 100;
    private const int minSides = 2;

    private Dice[] _dices;

    private List&lt;string&gt; _menuItems = new List&lt;string&gt;
    {
        &quot;Exit.&quot;,
        &quot;Setup Roll Dice.&quot;,
        &quot;Roll!&quot;
    };

    public void Run()
    {
        Console.Write(&quot;Welcome to Roll Dice!&quot;);
        while (true)
        {
            ShowMenu(_menuItems);
            switch (ConsoleHelper.ReadInteger(&quot;Enter your selection: &quot;, 0, _menuItems.Count - 1))
            {
                case 1:
                    Setup();
                    break;
                case 2:
                    Roll();
                    break;
                case 0:
                    Console.WriteLine(&quot;Bye.&quot;);
                    return;
                default:
                    Console.WriteLine(&quot;Error: Unexpected menu input!&quot;); // this would never happen
                    break;
            }
        }
    }

    private void Roll()
    {
        if (_dices == null)
        {
            Console.WriteLine(&quot;Please setup the Roll Dice first.&quot;);
            return;
        }

        Console.WriteLine(&quot;Rolling...&quot;);
        for (int i = 0; i &lt; _dices.Length; i++)
        {
            _dices[i].Roll();
        }
        Console.WriteLine($&quot;You rolled: {string.Join(&quot;, &quot;, (object[])_dices)}&quot;);

        int total = 0;
        for (int i = 0; i &lt; _dices.Length; i++)
        {
            total += _dices[i].Value;
        }
        Console.WriteLine($&quot;Total sum rolled is {total}&quot;);
    }

    private void Setup()
    {
        int diceCount = ConsoleHelper.ReadInteger(&quot;How many dice do you want to throw? &quot;, minDice, maxDice);
        int sides = ConsoleHelper.ReadInteger(&quot;How many sides does each dice have? &quot;, minSides, maxSides);
        _menuItems[1] = $&quot;Change Roll Dice setup. (currently {diceCount} dice of {sides} sides).&quot;;
        _dices = CreateDice(diceCount, sides);
    }

    private Dice[] CreateDice(int diceCount, int sides)
    {
        Dice[] dices = new Dice[diceCount];
        for (int i = 0; i &lt; diceCount; i++)
        {
            dices[i] = new Dice(sides);
        }
        return dices;
    }

    private void ShowMenu(List&lt;string&gt; items)
    {
        Console.WriteLine();
        for (int i = 1; i &lt; items.Count; i++)
            Console.WriteLine($&quot;[{i}] {items[i]}&quot;);
        Console.WriteLine($&quot;[0] {items[0]}&quot;);
    }
}

public class Dice
{
    private static Random rndGen = new Random(); // one random generator for all dices would be enough

    private int _sides;

    public int Value { get; private set; }

    public Dice(int sides)
    {
        _sides = sides;
    }

    public void Roll()
    {
        Value = rndGen.Next(0, _sides) + 1;
    }

    public override string ToString()
    {
        return $&quot;[{Value}]&quot;;
    }
}

public static class ConsoleHelper
{
    public static int ReadInteger(string prompt, int min, int max)
    {
        while (true)
        {
            Console.Write(prompt);
            if (int.TryParse(Console.ReadLine(), out int option) &amp;&amp; option &gt;= min &amp;&amp; option &lt;= max)
                return option;
            Console.WriteLine($&quot;You need to enter a valid number from {min} to {max}!&quot;);
        }
    }
}

Note for other reviewers: I'm not including const or readonly warnings in the review to leave it as simple as possible.
No recursion above.