list or switch

C

CSharper

I have a program which takes in various command line parameters and
each prefixed with a letter for eg:
/a:blush:ne /b:two etc.,
Currently I have a switch statement which phrases the parameter and
assigns the value after the parameter to corresponding private
variable. I have almost 19 case statements in the switch and most of
them are straight assignments. Just wondering, is there a better way
to do it, either using hash table or list or some other data structure
in C#?

Thanks,
 
C

Cowboy \(Gregory A. Beamer\)

A hashtable might be a bit faster, but with only 19 options it will not be
that much. The main reason to consider moving is refactoring for clarity. A
hashtable is obviously a lookup and you do not have to pour through case
statements to understand it.

--
Gregory A. Beamer
MVP, MCP: +I, SE, SD, DBA

Subscribe to my blog
http://feeds.feedburner.com/GregoryBeamer#

or just read it:
http://feeds.feedburner.com/GregoryBeamer

********************************************
| Think outside the box! |
********************************************
 
I

Ignacio Machin ( .NET/ C# MVP )

I have a program which takes in various command line parameters and
each prefixed with a letter for eg:
/a:blush:ne /b:two etc.,
Currently I have a switch statement which phrases the parameter and
assigns the value after the parameter to corresponding private
variable. I have almost 19 case statements in the switch and most of
them are straight assignments. Just wondering, is there a better way
to do it, either using hash table or list or some other data structure
in C#?

Thanks,

Hi,

You can create a Dictionary with all the possible values. This
dictionary can also be used durng the program to retrieve the values
of the arguments (I bet now you just have loose variables for that).
 
J

Jeroen Mostert

Cowboy said:
A hashtable might be a bit faster, but with only 19 options it will not
be that much.

I'm assuming the switch statement is on the option string, in which case it
will actually be no faster, since it's the same thing. Switching on strings
is translated to a hashtable lookup by the compiler, from a hashtable that's
initialized just about as efficiently as possible.
The main reason to consider moving is refactoring for
clarity. A hashtable is obviously a lookup and you do not have to pour
through case statements to understand it.
This, on the other hand, is a much more compelling reason to use an explicit
hashtable. A switch statement with 19 different options is much less
readable than a single hashtable lookup. Especially if you factor the
options out into their own type:

class Option {
public string ShortName { ... }
public string LongName { ... }
public string Help { ... }
// Etc.

Initialize hashtables from that or just use LINQ on an option collection and
away you go.
 
C

Cowboy \(Gregory A. Beamer\)

I am all for compelling. ;-)

I do like the idea of LINQ loading a hashtable. It is also very clear. It is
also nice to see people talking about LINQ for something other than a pseudo
DAL. :)

--
Gregory A. Beamer
MVP, MCP: +I, SE, SD, DBA

Subscribe to my blog
http://feeds.feedburner.com/GregoryBeamer#

or just read it:
http://feeds.feedburner.com/GregoryBeamer

********************************************
| Think outside the box! |
********************************************
 
J

Jeroen Mostert

Cowboy said:
I am all for compelling. ;-)

I do like the idea of LINQ loading a hashtable. It is also very clear.
It is also nice to see people talking about LINQ for something other
than a pseudo DAL. :)
LINQ is my golden hammer right now. :) I find myself using much less
"foreach" loops in favor of a .Select() call. I love functional programming,
and LINQ brings the most practical parts of it to C#.

I like LINQ to SQL too, because it allows you to concisely write DB access
classes (you don't even need the designer for that once you get the hang of
the attributes), but this is completely separate from LINQ to Objects (and
since I work at a shop where data access is done through stored procedures,
LINQ to SQL is of limited value to me anyway).
 
C

CSharper

Cowboy (Gregory A. Beamer) wrote:> I am all for compelling. ;-)


LINQ is my golden hammer right now. :) I find myself using much less
"foreach" loops in favor of a .Select() call. I love functional programming,
and LINQ brings the most practical parts of it to C#.

I like LINQ to SQL too, because it allows you to concisely write DB access
classes (you don't even need the designer for that once you get the hang of
the attributes), but this is completely separate from LINQ to Objects (and
since I work at a shop where data access is done through stored procedures,
LINQ to SQL is of limited value to me anyway).

J,

I have a question on the last subject you are talking about. I am
using LINQ with XML a lot bit I know LINQ provides same amount
features to collection as well. But I don't understand how would you
replace a 'foreach' loop with a select? Do you mind to elobarate a
little bit for me?
Thanks,
 
C

CSharper

A hashtable might be a bit faster, but with only 19 options it will not be
that much. The main reason to consider moving is refactoring for clarity.A
hashtable is obviously a lookup and you do not have to pour through case
statements to understand it.

--
Gregory A. Beamer
MVP, MCP: +I, SE, SD, DBA

Subscribe to my bloghttp://feeds.feedburner.com/GregoryBeamer#

or just read it:http://feeds.feedburner.com/GregoryBeamer

********************************************
| Think outside the box!                               |

Here is the reason for my question; I have added the following method
to create a hashtable and in that I need to traverse the argument list
like the following

public static bool AssignParamters(string[] args)
{
if (myArguments == null)
myArguments = new Hashtable();
foreach (string argument in args)
{
if (argument.Length >= 2)
myArguments.Add(argument.Substring(0,
2).ToUpper(), (argument.Length > 3) ?
argument.Substring(2).ToUpper() : "true");
}
return true;
}
 
J

Jeroen Mostert

CSharper said:
I have a question on the last subject you are talking about. I am
using LINQ with XML a lot bit I know LINQ provides same amount
features to collection as well. But I don't understand how would you
replace a 'foreach' loop with a select? Do you mind to elobarate a
little bit for me?

Here's a good example: I've got a bunch of strings and I want to join them
as comma-separated values, taking care to escape them with quotes. I can do
it like this:

string csv;
var sb = new StringBuilder();
foreach (string s in myStrings) {
sb.Append('"' + s.Replace("\"", "\"\"") + '"' + ", ");
}
csv = sb.ToString(0, sb.Length > 0 ? sb.Length - 2 : 0);

This focuses on "how" rather than "what". This doesn't:

csv = string.Join(", ", myStrings.Select(s => '"' + s.Replace("\"",
"\"\"") + '"').ToArray());

Of course, I'm cheating because string.Join() already exists. If it didn't
we would probably write it as an extension method:

public static string Join(this IEnumerable<string> source, string
separator) {
var sb = new StringBuilder();
foreach (string s in source) {
sb.Append(s);
sb.Append(separator);
}
return sb.ToString(0, sb.Length > 0 ? sb.Length - 2 : 0);
}

Looks familiar, doesn't it? How does this avoid foreach? The benefit here is
that we only write down the "how" of joining one time, separating it from
escaping, and we can use this on every sequence of strings in the future.
While we're at it, let's write another function:

public static string DoubleEscape(this string s, char escapeCharacter) {
string escapeString = new string(escapeCharacter, 2);
return escapeCharacter + s.Replace(escapeCharacter, escapeString) +
escapeCharacter;
}

And now our CSV-encoding looks like this:

csv = myStrings.Select(s => s.DoubleEscape('"')).Join(", ");

You can't get much clearer than that.

Of course, you can't literally replace every foreach loop with a select, nor
is that desireable. If you really have to invoke methods on objects to
change it, a foreach loop is the way to go. Even if you could use LINQ for
that, you wouldn't want to, since LINQ should be used free of side effects.
 
C

CSharper

Here's a good example: I've got a bunch of strings and I want to join them
as comma-separated values, taking care to escape them with quotes. I can do
it like this:

   string csv;
   var sb = new StringBuilder();
   foreach (string s in myStrings) {
     sb.Append('"' + s.Replace("\"", "\"\"") + '"' + ", ");
   }
   csv = sb.ToString(0, sb.Length > 0 ? sb.Length - 2 : 0);

This focuses on "how" rather than "what". This doesn't:

   csv = string.Join(", ", myStrings.Select(s => '"' + s.Replace("\"",
"\"\"") + '"').ToArray());

Of course, I'm cheating because string.Join() already exists. If it didn't
we would probably write it as an extension method:

   public static string Join(this IEnumerable<string> source, string
separator) {
     var sb = new StringBuilder();
     foreach (string s in source) {
       sb.Append(s);
       sb.Append(separator);
     }
     return sb.ToString(0, sb.Length > 0 ? sb.Length - 2 : 0);
   }

Looks familiar, doesn't it? How does this avoid foreach? The benefit hereis
that we only write down the "how" of joining one time, separating it from
escaping, and we can use this on every sequence of strings in the future.
While we're at it, let's write another function:

   public static string DoubleEscape(this string s, char escapeCharacter) {
     string escapeString = new string(escapeCharacter, 2);
     return escapeCharacter + s.Replace(escapeCharacter, escapeString) +
escapeCharacter;
   }

And now our CSV-encoding looks like this:

   csv = myStrings.Select(s => s.DoubleEscape('"')).Join(", ");

You can't get much clearer than that.

Of course, you can't literally replace every foreach loop with a select, nor
is that desireable. If you really have to invoke methods on objects to
change it, a foreach loop is the way to go. Even if you could use LINQ for
that, you wouldn't want to, since LINQ should be used free of side effects.

Thanks J, it explains very well.
 

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