Switch messed up or there is a reason for the madness?

M

Meya-awe

Hi, i am new to C#. I am using some code similar to the one below. I am
declaring an ArrayList in one case block but the compiler complains
about it already being used in the previous case block. Is this normal
in C#? Assume that i follow this and in the first case block, i allocate
the memory using the "ArrayList mylist=new ArrayList()", and in the
second block, i just use the variable mylist like
"mylist.Add(something)". Now if the switch statement executes the second
case block first, that would case a violation, wouldn't it?

private void button1_Click(object sender, EventArgs e)
{
switch (button1.Text)
{
case "button1":
ArrayList mylist = new ArrayList();
mylist.Add(button1.Text);
button1.Text = "button2";
break;
case "button2":
ArrayList mylist = new ArrayList();
mylist.Add(button1.Text);
button1.Text = "button1";
break;
default:
break;
}
}
BRAMOIN
 
T

Tom Spink

Hi, can you post the exact error you get out of the compiler, please?

Thanks!

-- Tom
 
J

Jon Skeet [C# MVP]

Meya-awe said:
Hi, i am new to C#. I am using some code similar to the one below. I am
declaring an ArrayList in one case block but the compiler complains
about it already being used in the previous case block. Is this normal
in C#? Assume that i follow this and in the first case block, i allocate
the memory using the "ArrayList mylist=new ArrayList()", and in the
second block, i just use the variable mylist like
"mylist.Add(something)". Now if the switch statement executes the second
case block first, that would case a violation, wouldn't it?

It's irritating, but the scope of a variable declared in a switch block
is the *whole* switch block, not just the case you're in. However, if
you put braces round your case blocks, it should be okay.
 
M

Marcus Andrén

private void button1_Click(object sender, EventArgs e)
{
switch (button1.Text)
{
case "button1":
ArrayList mylist = new ArrayList();
mylist.Add(button1.Text);
button1.Text = "button2";
break;
case "button2":
ArrayList mylist = new ArrayList();
mylist.Add(button1.Text);
button1.Text = "button1";
break;


As Jon Skeet said you could use {} inside the case blocks.

case 1:
{
ArrayList mylist = new ArrayList();
break;
}
case 2:
{
ArrayList mylist = new ArrayList();
break;
}

The other possibility is to accept that a declaration lasts over the
whole switch statement and only declare the ArrayList in the first
case.

case "button1":
ArrayList mylist = new ArrayList();
break;
case "button2":
mylist = new ArrayList();
break;

While not very logical, it does work just fine.
 
M

Meya-awe

Thanks for everyone's response on this. The first part of my questions
is how to get around this. And Jon already pointed this out. I will use
the braces. The second part of my question is why was this changed in C#
to treat the variable's scope global to the entire switch statement.

BRAMOIN
 
M

Meya-awe

Tom,
Here is the exact error message, may be this was requested for
historical reason? Please let me know if i was confusing in my
statements or what?

Error 2 A local variable named 'mylist' is already defined in this
scope C:\visual studio
2005\Projects\TestingSwitchVariableScope\TestingSwitchVariableScope\Form
1.cs 29 31 TestingSwitchVariableScope
thx,
BRAMOIN
 
M

Mark Wilden

What is the purpose of this code? It doesn't seem useful to declare a
variable inside a switch statement unless its use has side effects.
 
J

Jon Skeet [C# MVP]

Mark Wilden said:
What is the purpose of this code? It doesn't seem useful to declare a
variable inside a switch statement unless its use has side effects.

I always declare variables as close as I can to first use, and in the
tightest scope possible. Sure, the ArrayLists in this example aren't
being used, but it's reasonable to assume that in the real world, the
variable is actually useful.
 
M

Meya-awe

Yes, Jon is correct, it is best to declare the variables as close as
first use. The practical application is when you have a routine where
it handles a specific set of sequences or cases (for example, a handler
which plots the next course for an airplane, gets notified every second
that it has to compute a new direction for an airplane, once it gets
notified, it 500msecs before the data becomes available for it to
compute a trajectory, the trajectory and all data needs to be saved
everytime a course is plotted [i.e. a new block of memory is required to
plot the next course]). In one of the cases, you always want to setup
memory so in the subsequent cases you would not have to do this and can
do computation. Hope this makes sense.

BRAMOIN
 
M

Mark Wilden

I agree about declaring variables close to their use. I was, however,
commenting on the specific code that was posted.

In general, I would say that declaring a variable inside a switch
statement constitutes a "code smell," and that the code should probably
be factored into a function of its own.

Which is not to say I've never done it, and used the block trick, which
is also necessary in C and C++, not just in C# (in reply to another
poster).
 
J

Jon Skeet [C# MVP]

Mark Wilden said:
I agree about declaring variables close to their use. I was, however,
commenting on the specific code that was posted.

In general, I would say that declaring a variable inside a switch
statement constitutes a "code smell," and that the code should probably
be factored into a function of its own.

Which is not to say I've never done it, and used the block trick, which
is also necessary in C and C++, not just in C# (in reply to another
poster).

I've used it reasonably often - it's quite easy to get into a situation
where you don't really *need* a variable, but you refer to the same
expression three times in three lines of code - adding an extra
variable can help a lot, and refactoring to a method often doesn't make
a lot of sense. (Don't get me wrong, I'm in favour of refactoring where
appropriate, and I don't like *large* case blocks, but a few lines is
okay.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top