You can't declare extra variables at execution time in C# - but you really don't want to anyway, as you wouldn't be able to access them dynamically afterwards. Just create an array:
// buttons would be declared as Button[] as a member variable
buttons = new Button[30];
for(int i = 0; i < buttons.Length; i++) {
buttons[i] = new Button();
// Button customization here...
...
groupBox1.Controls.Add(buttons[i]);
}
Alternatively, use a List<Button>, which will certainly be more convenient if you don't know how many buttons you need beforehand. (See the obligatory "arrays considered somewhat harmful" blog post.)
Of course, if you don't actually need to get at the buttons later, don't bother assigning them to anything visible outside the loop:
for(int i = 0; i < 30; i++) {
Button button = new Button();
// Button customization here...
...
groupBox1.Controls.Add(button);
}
You need to think about what information you need access to when... and how you want to access it. If you logically have a collection of buttons, you should use a collection type variable (like a list or an array).
Frankly I think it's one of the curses of the VS designers that you end up with horrible names such as "groupBox1" which carry no information beyond what's already in the type declaration, and encourage developers to think of collections of controls via individually-named variables. That's just me being grumpy though :)