|
Heh heh ... to be fair, I've been learning C# since February and it wouldn't be the first time that I've come across something in the language and other more experienced folks have said to me "oooh ... you really don't want to use that ... that's bad" or similar.
And like everything there is more than one way to skin a cat. I'm sure I could design out the need for the switch statements I've used so far if I really wanted too ...
|
|
|
|
|
IMO it comes down to the resulting compiled code.
The ability of a computer to branch based on a decision is
powerful, and taken for granted these days.
So, when designing a high level language, where you want the
ability to branch based on a list of comparisons, what are the
alternatives? One can do it explicitly with if/then/else but that
can be inefficient for the decision at the end of a big list.
To avoid that inefficiency some kind of look-up table may be more efficient.
Theoretically, using the switch semantics, a good compiler could
recognize a big list and produce more efficient branching code - possibly
using a look-up table of some kind. The restrictions of the switch statement
allows this.
Here's a C++ example ( completely OT for this forum, but demonstrates my point):
int i = 6;
if (i == 0)
TRACE0("0");
else if (i == 1)
TRACE0("1");
else if (i == 2)
TRACE0("2");
else if (i == 3)
TRACE0("3");
else if (i == 4)
TRACE0("4");
else if (i == 5)
TRACE0("5");
else if (i == 6)
TRACE0("6");
else
TRACE0("n");
switch (i)
{
case 0:
TRACE0("0");
break;
case 1:
TRACE0("1");
break;
case 2:
TRACE0("2");
break;
case 3:
TRACE0("3");
break;
case 4:
TRACE0("4");
break;
case 5:
TRACE0("5");
break;
case 6:
TRACE0("6");
break;
default:
TRACE0("n");
break;
}
The resulting if/else machine code does six comparisons to get
to the resulting branch.
The resulting switch machine code does one comparison to see if
i is > 6, and if it isn't, branches directly to the correct case
using only TWO machine code instructions (via a look-up table)
0041D9F5 mov ecx,dword ptr [ebp-0AE4h]
0041D9FB jmp dword ptr (41F8CCh)[ecx*4]
switch may be ugly in source code, but the compiler can certainly
take advantage of it to produce efficient code.
And I don't buy the "purist programmer" arguments...what purist would
use C# (or any other higher level language)?
It still all comes down to knowing the language you're using and
choosing the right instructions for the given situation...
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Great example! Thanks for this ...
|
|
|
|
|
Heh no problem. I work alone at home - I don't get to
have these water-cooler discussions with colleagues
Cheers!
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
heh ... they can be really beneficial! Although I'm still at a stage in learning .NET where I come away with more questions than answers!
Doh!
|
|
|
|
|
|
|
Hmm, in my opinion why would it be incorrect to use a reserved keyword that's included in a language... Of course switch is much more limited compared to if-statement, but then again if used nicely it's really readable.
When reading long if-else-if-else... structures they easily take away the focus from the action that's executed if (simple) condition matches. Also in a multimatch situation, switch is very nice compared to or logic in if statements or duplicated code if or is not used.
However, is switch better than if in some case would greately be a matter of writing style (clarity above all ).
Mika
The need to optimize rises from a bad design.
My articles[ ^]
|
|
|
|
|
|
Actually, if you have more than just a few case labels in a switch (four IIRC), it's implemented using a dictionary.
Despite everything, the person most likely to be fooling you next is yourself.
|
|
|
|
|
Yeah, more than five, as you showed back in July. I keep forgetting that.
On the other hand, using your own Dictionary gives you more flexibility and the ability to use it in multiple places (if you can think of such a use).
|
|
|
|
|
Not to beat the "dead horse" here, but I didn't see anyone bring up the induced complexity that the switch adds. See complexity definition here.[^] The higher the complexity score, the more trouble maintenance and testing become. The switch is very efficient at adding additional paths in the code (cases - 1).
While yes, the readability is there, one could argue at the same time a certain amount of flexibility is lost at the expense. There are more or less feasible ways around using a switch or bank of if/else altogether - using the chain-of-responsibility pattern has worked for me in some situations. And certainly it has made unit testing easier.
I might correct your colleague's statement and submit that maybe the architecture isn't "wrong" by using a switch, it just might be pointing out that there are higher quality alternatives.
Scott P.
"Simplicity carried to the extreme becomes elegance."
-Jon Franklin
|
|
|
|
|
carbon_golem wrote: there are higher quality alternatives.
Agreed. See my post below, that you just beat to the wire! Damn you!
led mike
|
|
|
|
|
carbon_golem wrote: it just might be pointing out that there are higher quality alternatives.
You mean like "goto"?
LOLOL
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997 ----- "...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001
|
|
|
|
|
Jammer wrote: What do other folks think of this?
It's not Object Oriented and the following is a section of my own notes to myself (quotes ) from Kent Becks book "Implementation Patterns"
<w:worddocument xmlns:w="#unknown"><w:punctuationkerning><w:validateagainstschemas><w:compatibility><w:breakwrappedtables><w:snaptogridincell><w:wraptextwithpunct>
<p class="MsoNormal">Conditional (page 36)</p><p class="MsoNormal">If/then and switch statements are the simplest form of
instance –specific behavior….</p><p class="MsoNormal">The more paths through a program the less likely the program
is to be correct….The proliferation of conditionals reduces reliability….This
problem is compounded when conditionals are duplicated.</p>
<p class="MsoNormal">These problems can all be eliminated by converting the
conditional logic to messages, either with subclasses or delegation.</p>
Last modified: 5hrs 28mins after originally posted --
led mike
|
|
|
|
|
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Wow what a mess. Fixed. Thanks
|
|
|
|
|
Well, your colleague is a moron, and it sound s like his father should have used a switch on him more often when he was a child.
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997 ----- "...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001
|
|
|
|
|
Whoa ... it wasn't my colleague that stated this ... he was passing on things he'd read/heard ... it was a light-hearted conversation!
He is far from a Moron as well, a very good developer in fact.
|
|
|
|
|
Jammer wrote: He said that he'd read/heard more than once that if you find yourself using a switch you can more or less be assured that its because you've done something wrong in your architecture elsewhere.
That probably comes from someone who don't know how to use a switch properly...
What seems more elegant?
This:
int result;
SomeClass.SomeEnum value = SomeClass.GetValue();
if (value == SomeClass.SomeEnum.Option1 || value == SomeClass.SomeEnum.Option2) {
result = 1;
} else if (value == SomeClass.SomeEnum.Option3) {
result = 2;
} else if (value == SomeClass.SomeEnum.Option4 || value == SomeClass.SomeEnum.Option5 || value == SomeClass.SomeEnum.Option6) {
result = 3;
} else {
result = 4;
}
or this:
int result;
switch (SomeClass.GetValue()) {
case SomeClass.SomeEnum.Option1:
case SomeClass.SomeEnum.Option2: result = 1; break;
case SomeClass.SomeEnum.Option3: result = 2; break;
case SomeClass.SomeEnum.Option4:
case SomeClass.SomeEnum.Option5:
case SomeClass.SomeEnum.Option6: result = 3; break;
default: result = 4; break;
}
Besides, the switch solution is faster.
Despite everything, the person most likely to be fooling you next is yourself.
|
|
|
|
|
It depends on the situation. There are definitely situations where I've seen needless use of switch statements, and others that would have benefitted from a switch statement.
If you find that you are switching on a specific property of a class a lot within that class then it can be an indication that you might want to refactor the code into a class hierarchy. Each derived class handles a specific case that was in the switch statement.
|
|
|
|
|
As others said, switch statement has many benefits. So use it wisely. You should read something about method cohesion[^].
|
|
|
|
|
Hello friends,
I'm writing a program that reads all the files in a specified folder and stores their attributes in a MS-Access database. I'm using the FileInfo, and the FileVersionInfo classes to query file attributes. But these classes don't expose properties or methods to query advanced attributes such as image dimensions, ablum title, etc. I googled to find out the answer and it came up with GetDetailsOf method of shell32.dll. It seems that the GetDetailsOf method would be a perfect fit for my purpose as I only need to read that info. But what is really worrying me is its portability. The second argument is an integer and it specifies the info. to be retrieved. Is its value consistent across all Windows versions. I just want to make sure that I don't get two different values for the same file, with the same integer value under different Windows versions.
Many thanks in advance
|
|
|
|
|
Yes, those constants are the same from version to version. They won't change the constants, only add to them.
Ankit Rajpoot wrote: But what is really worrying me is its portability.
What's your definition of "portability" and your concerns? Which platforms are you going to look at supporting? Or were you just referring to the constants passed to the GetDetailsOf method?
|
|
|
|
|
Hello Sir,
I'm planning to support Win98 and later versions of Windows. I've Windows XP SP2 on my Development machine. So I need to make sure that the code that I write and test on Xp runs on earlier versions too and on Vista too.
What I'm worried about is that the constant-value to file-attribute mapping is same on all Windows versions or not. For example, passing 15 returns the Artist's name from the file. Is it true for all Windows versions.
|
|
|
|