473,397 Members | 2,099 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,397 software developers and data experts.

switch on string value

Hi

i have a string variable which can take one of a set of many values.
Depending on the value I need to take different (but related) actions. So I
have a big if/else-if construct - but what is a better way of doing this?

if ("control" == commandString)
{
}
else if ("execute" == commandString)
{
}
else if ("send" == commandString")
{
}
else if ( ....

etc
Thanks,
Peter
Nov 29 '06 #1
11 10828
Well, switch (on a string) would automatically compile to a hashtable for
performance; however you could look at enums. Alternatively a dictionary of
delegates might be in order...

Marc
Nov 29 '06 #2
Marc Gravell wrote:
Well, switch (on a string) would automatically compile to a hashtable for
performance; however you could look at enums. Alternatively a dictionary of
delegates might be in order...

Marc

Enums seem appropriate here for simplicity, however these enum/switch
kind of scenarios are usually interchangeable with the Strategy pattern,
(if you're up to some more coding):

http://www.dofactory.com/Patterns/PatternStrategy.aspx

Wiebe
Nov 29 '06 #3
Tom
Short answer...this is how your switch would look

switch (commandString.ToLower())
{
case "control":
//do code unique to this case
FunctionCallToDoCommonCodeToAllCases();
break;
case "execute":
//do code unique to this case
FunctionCallToDoCommonCodeToAllCases();
break;
}

etc etc

Peter Kirk wrote:
Hi

i have a string variable which can take one of a set of many values.
Depending on the value I need to take different (but related) actions. So I
have a big if/else-if construct - but what is a better way of doing this?

if ("control" == commandString)
{
}
else if ("execute" == commandString)
{
}
else if ("send" == commandString")
{
}
else if ( ....

etc
Thanks,
Peter
Nov 29 '06 #4
Hi Peter

You should generally try not to switch on a string. As suggested
earlier it is better to convert your string to an enum

static public TNewEnum ConvertTo<TNewEnum>(object input)
{
return (TNewEnum)Enum.Parse(typeof(TNewEnum),
input.ToString(), true);
}

and then perform your switch on the enum

On Nov 30, 5:41 am, "Tom" <thomas.f.ty...@wamu.netwrote:
Short answer...this is how your switch would look

switch (commandString.ToLower())
{
case "control":
//do code unique to this case
FunctionCallToDoCommonCodeToAllCases();
break;
case "execute":
//do code unique to this case
FunctionCallToDoCommonCodeToAllCases();
break;
}

etc etc

Peter Kirk wrote:
Hi
i have a string variable which can take one of a set of many values.
Depending on the value I need to take different (but related) actions. So I
have a big if/else-if construct - but what is a better way of doing this?
if ("control" == commandString)
{
}
else if ("execute" == commandString)
{
}
else if ("send" == commandString")
{
}
else if ( ....
etc
Thanks,
Peter
Nov 29 '06 #5
ni***********@iinet.net.au wrote:
You should generally try not to switch on a string. As suggested
earlier it is better to convert your string to an enum

static public TNewEnum ConvertTo<TNewEnum>(object input)
{
return (TNewEnum)Enum.Parse(typeof(TNewEnum),
input.ToString(), true);
}

and then perform your switch on the enum
What extraordinary advice! Why do you say this? Do you imagine that a
switch on an enum is clearer? Surely you cannot imagine that this is
faster than switching on a string value?

Switching on a string value involves doing a series of inline
comparisons. The enum approach involves calling a method that calls a
method that gets a table of enum strings from metadata then scans that
table and boxes the result; then casts the boxed enum to an enum and
returns the unboxed enum; then doing a switch on the unboxed enum.

--

..NET 2.0 for Delphi Programmers
www.midnightbeach.com/.net
What you need to know.
Nov 29 '06 #6
I agree; I don't see the value of converting to an enum just to perform
the switching. However if these strings logically grouped per the
overall program design, then maybe making them an enum in the first
place is appropriate; i.e. "... different (but related) actions."

That said, I've always been a fan of "switch" over "if / else if".
IMHO it's easer to read, less error-prone during changing - especially
if the "if/else if" programmer doesn't use braces for single statement
branches; now the reader has to stop and think a bit to make sure (s)he
is reading it correctly. Finally there's the switch's "default" which,
for me, tends to make me code an error trap; yeah, I know "default" is
optional, but it's saved me a couple of times catching one of those
mythical "can't ever happen" errors.

On 2006-11-29 16:51:39 -0600, Jon Shemitz <jo*@midnightbeach.comsaid:
ni***********@iinet.net.au wrote:
>You should generally try not to switch on a string. As suggested
earlier it is better to convert your string to an enum

static public TNewEnum ConvertTo<TNewEnum>(object input)
{
return (TNewEnum)Enum.Parse(typeof(TNewEnum),
input.ToString(), true);
}

and then perform your switch on the enum

What extraordinary advice! Why do you say this? Do you imagine that a
switch on an enum is clearer? Surely you cannot imagine that this is
faster than switching on a string value?

Switching on a string value involves doing a series of inline
comparisons. The enum approach involves calling a method that calls a
method that gets a table of enum strings from metadata then scans that
table and boxes the result; then casts the boxed enum to an enum and
returns the unboxed enum; then doing a switch on the unboxed enum.

Nov 29 '06 #7
I think Bob has a really good point: readability. Switch seems to me
(and apparently Bob) to be the easiest to read and therefore maintain.

Other methods (enums, strategy pattern) are valid and I'm sure they
work. There are probably scalability and performance concerns. I think
enums may be fastest, although I have no proof either way. The strategy
pattern probably scales the best: no one wants to read a switch
statement with 100 possible values.

Look at the rest of the requirements. Is high performance essential,
which has the implied and must-be-tested meaning that a switch
statement is not fast enough? Are there a whole lot of switches? If
it's just a three-way split in a non-performance critical section,
switch is probably the simplest.
Stephan

Bob Jones wrote:
I agree; I don't see the value of converting to an enum just to perform
the switching. However if these strings logically grouped per the
overall program design, then maybe making them an enum in the first
place is appropriate; i.e. "... different (but related) actions."

That said, I've always been a fan of "switch" over "if / else if".
IMHO it's easer to read, less error-prone during changing - especially
if the "if/else if" programmer doesn't use braces for single statement
branches; now the reader has to stop and think a bit to make sure (s)he
is reading it correctly. Finally there's the switch's "default" which,
for me, tends to make me code an error trap; yeah, I know "default" is
optional, but it's saved me a couple of times catching one of those
mythical "can't ever happen" errors.

On 2006-11-29 16:51:39 -0600, Jon Shemitz <jo*@midnightbeach.comsaid:
ni***********@iinet.net.au wrote:
You should generally try not to switch on a string. As suggested
earlier it is better to convert your string to an enum

static public TNewEnum ConvertTo<TNewEnum>(object input)
{
return (TNewEnum)Enum.Parse(typeof(TNewEnum),
input.ToString(), true);
}

and then perform your switch on the enum
What extraordinary advice! Why do you say this? Do you imagine that a
switch on an enum is clearer? Surely you cannot imagine that this is
faster than switching on a string value?

Switching on a string value involves doing a series of inline
comparisons. The enum approach involves calling a method that calls a
method that gets a table of enum strings from metadata then scans that
table and boxes the result; then casts the boxed enum to an enum and
returns the unboxed enum; then doing a switch on the unboxed enum.
Nov 29 '06 #8
ssamuel wrote:
enums may be fastest
Only if the input is already an enum, but the OP specified a string.

Using Rick Fletcher's ConvertTo, I benchmark switch on string as
about 2.5 times faster than switch on enum-from-string.

// Shemitz.Utilities is available at
// www.midnightbeach.com/.net/source.code

using System;
using System.Collections.Generic;
using System.Text;
using Shemitz.Utilities;

namespace SwitchOnStringOrEnum
{
class Program
{
static void Main(string[] args)
{
const int Iterations = 10;

string Control = "CONTROL".ToLower(); // avoid interning ... strings should not be reference-equal
string Execute = "EXECUTE".ToLower();
string Send = "SEND".ToLower();

Method OnString = delegate
{
for (int Index = 0; Index < Iterations; Index++)
{
SwitchOnString(Control);
SwitchOnString(Execute);
SwitchOnString(Send);
}
};
Method OnEnum = delegate
{
for (int Index = 0; Index < Iterations; Index++)
{
SwitchOnEnum(Control);
SwitchOnEnum(Execute);
SwitchOnEnum(Send);
}
};

using (new Benchmark())
{
OnString();
OnEnum();
}

using (new Benchmark("Switch on string"))
OnString();
using (new Benchmark("Switch on enum"))
OnEnum();

Console.ReadLine();
}

private static int SwitchOnString(string Input)
{
switch (Input)
{
case "control":
return 0;
case "execute":
return 1;
case "send":
return 2;
default:
return -1;
}
}

private static int SwitchOnEnum(string Input)
{
switch (ConvertTo<Commands>(Input))
{
case Commands.control:
return 0;
case Commands.execute:
return 1;
case Commands.send:
return 2;
default:
return -1;
}
}

static public TNewEnum ConvertTo<TNewEnum>(object input)
{
return (TNewEnum)Enum.Parse(typeof(TNewEnum), input.ToString(), true);
}
}

delegate void Method();

enum Commands { control, execute, send };
}
--

..NET 2.0 for Delphi Programmers
www.midnightbeach.com/.net
What you need to know.
Nov 30 '06 #9
I neither suggested nor implied that Peter should implement the
solution as you have outlined. I merely stated that it is better to
switch on a enum rather than a string and provided a method by which
you could perform a conversion.

Obviously performing such an operation every time the switch is
evaluated is going to be slower.

On Nov 30, 11:42 am, Jon Shemitz <j...@midnightbeach.comwrote:
ssamuel wrote:
enums may be fastestOnly if the input is already an enum, but the OP specified a string.

Using Rick Fletcher's ConvertTo, I benchmark switch on string as
about 2.5 times faster than switch on enum-from-string.

// Shemitz.Utilities is available at
//www.midnightbeach.com/.net/source.code

using System;
using System.Collections.Generic;
using System.Text;
using Shemitz.Utilities;

namespace SwitchOnStringOrEnum
{
class Program
{
static void Main(string[] args)
{
const int Iterations = 10;

string Control = "CONTROL".ToLower(); // avoid interning ... strings should not be reference-equal
string Execute = "EXECUTE".ToLower();
string Send = "SEND".ToLower();

Method OnString = delegate
{
for (int Index = 0; Index < Iterations; Index++)
{
SwitchOnString(Control);
SwitchOnString(Execute);
SwitchOnString(Send);
}
};
Method OnEnum = delegate
{
for (int Index = 0; Index < Iterations; Index++)
{
SwitchOnEnum(Control);
SwitchOnEnum(Execute);
SwitchOnEnum(Send);
}
};

using (new Benchmark())
{
OnString();
OnEnum();
}

using (new Benchmark("Switch on string"))
OnString();
using (new Benchmark("Switch on enum"))
OnEnum();

Console.ReadLine();
}

private static int SwitchOnString(string Input)
{
switch (Input)
{
case "control":
return 0;
case "execute":
return 1;
case "send":
return 2;
default:
return -1;
}
}

private static int SwitchOnEnum(string Input)
{
switch (ConvertTo<Commands>(Input))
{
case Commands.control:
return 0;
case Commands.execute:
return 1;
case Commands.send:
return 2;
default:
return -1;
}
}

static public TNewEnum ConvertTo<TNewEnum>(object input)
{
return (TNewEnum)Enum.Parse(typeof(TNewEnum), input.ToString(), true);
}
}

delegate void Method();

enum Commands { control, execute, send };

}--

.NET 2.0 for Delphi Programmerswww.midnightbeach.com/.net
What you need to know.
Nov 30 '06 #10
"Peter Kirk" <pk@alpha-solutions.dkskrev i en meddelelse
news:ul**************@TK2MSFTNGP02.phx.gbl...
if ("control" == commandString)
{
}
else if ("execute" == commandString)
{
}
else if ("send" == commandString")
{
}
else if ( ....
Hi again. Thanks for all the comments. My code is a small part of a larger
system. I receive an object in my method, and in this object is a string
property which I must check to determine what action I should take. There is
a set of about 15 string values this property can take - but it is not an
enum, it is a string.

I guess I could convert to an "enum" value and use that, or I could have
just used switch/case. My initial code was simply a really long if/else
construct.

Now I have tried a dictionary of delegate methods. I really have no idea of
performance issues, but the code _appears_ cleaner in my class, due to the
fact that I don't have a huge if/else. I do however have a large constructor
where I initialise the dictionary... still, it was also the first time I
ever looked at delegates, so I consider it a learning experience.
thanks again,
Peter
Nov 30 '06 #11
Peter Kirk wrote:
I guess I could convert to an "enum" value and use that, or I could have
just used switch/case. My initial code was simply a really long if/else
construct.
Just to summarize the thread to date on this: Switching on an enum
*is* faster than switching on a string. (The compiler may use a vector
table; even if it just uses a series of comparisons, the comparisons
are cheaper.) However, converting the string to an enum more than
wipes out the dispatch gains, and is only worthwhile if you can use
the enum several times.
Now I have tried a dictionary of delegate methods. I really have no idea of
performance issues, but the code _appears_ cleaner in my class, due to the
fact that I don't have a huge if/else. I do however have a large constructor
where I initialise the dictionary... still, it was also the first time I
ever looked at delegates, so I consider it a learning experience.
I was thinking about this thread last night, and was going to suggest
a Dictionary.

For the three terms you initially showed, a Dictionary is probably
going to be slower than a switch - there's a certain amount of
overhead in computing commandString.GetHashCode() and traversing the
buckets. By fifteen terms, the Dictionary should be competitive, and
may even be faster; certainly the Dictionary will hold up better as
the app evolves and adds more commands.

Dictionary dispatch is much smaller and clearer than the big switch
statement. Of course, as you've found, you've simply moved the
complexity into the code that populates the Dictionary. However, you
can 'distribute' the code that populates the Dictionary, which reduces
the clutter and makes it easier to maintain as you add commands.

* If command handling is spread over multiple subsystems, you can have
each subsystem 'register' handlers when the subsystem is initialized.
That is, each subsystem's constructor would register its own
delegates.

* If all the command handling is done (or at least initiated) in
methods of the dispatching class, you can use custom attributes to
mark command handling methods. Instead of a long series of
`Dispatch["control"] = ControlHandler;` statements, you'd decorate the
ControlHandler method with an attribute like
`[CommandHandler("control")]`, and your Dictionary population code
would just look for methods with the CommandHandler attribute, and get
the command string from the attribute. The Dictionary population code
is more complex, but it's smaller and doesn't have to be modified when
you add a new command; you just add the command handler and the
attribute ensures registration.

--

..NET 2.0 for Delphi Programmers
www.midnightbeach.com/.net
What you need to know.
Nov 30 '06 #12

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

10
by: Myster Ious | last post by:
Polymorphism replaces switch statements, making the code more compact/readable/maintainable/OO whatever, fine! What I understand, that needs to be done at the programming level, is this: a...
13
by: webzila | last post by:
Hello, I have to write a program for an 8051 micro-controller using micro-C to monitor Switch 1 and if the switch in pushed the message "switch 1 pushed" should be displayed in the LCD. Also the...
8
by: _eddie | last post by:
Is there a good way to code a switch/case-type construct for maximal speed? The goal is to parse text key/value pairs. IOW: // key = "Text of some kind" // value = "Value Text" string...
3
by: pgraeve | last post by:
I am a convert from VB to C# so bear with me on this "conversion" question C# switch statement seems to be the closest relative to VB's Select Case. I used VB's Select Case statement liberally. ...
27
by: Yuriy Solodkyy | last post by:
Hi VS 2005 beta 2 successfully compiles the following: using System; using System.Collections.Generic; using System.Text; namespace ConsoleApplication1 { class Program {
16
by: ME | last post by:
In C# the following code generates a compiler error ("A constant value is expected"): public void Test(string value) { switch (value) { case SimpleEnum.One.ToString(): MessageBox.Show("Test...
4
by: priyanka | last post by:
Hi there, I had a question. Is there any way of testing a string value in a switch statement. I have about 50 string values that can be in a string variable. I tried cheking them with the if...
9
by: mantrid | last post by:
hello In the function below radtext is an array of 3 radio buttons with values set to 1, 2 and 3. but variables starty and finishy are not returned. ...
12
by: | last post by:
Is it fine to call another method from Switch? Eg. Switch (stringVar) { case ("a"): somVar = "whatever"; Another_Method(); //call another method return;
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.