Wednesday, December 10, 2008

Delimiters

Let’s talk about string delimiters and why you shouldn’t hard code them. Take the following example.

   16 return String.Format("#Command#{0}#{1}#{2}#{3}#{4}#{5}#{6}#{7}#{8}#{9}", completePath,
   17                                                                       GUID,
   18                                                                       UID,
   19                                                                       otherinfo,
   20                                                                       option1,
   21                                                                       displayText,
   22                                                                       filter,
   23                                                                       someint.ToString(),
   24                                                                       file,
   25                                                                       seckret);

It and three other ones just like it can be found in the code I am currently working on. Now when you see this you think that isn’t all that bad. Until you need to change the delimiter for one reason or another. You could go with something like the following but it not the most readable thing you will ever see.

   28 return String.Format("{10}Command{10}{0}{10}{1}{10}{2}{10}{3}{10}{4}{10}{5}{10}{6}{10}{7}{10}{8}{10}{9}",
   29                                                                       completePath,
   30                                                                       GUID,
   31                                                                       UID,
   32                                                                       otherinfo,
   33                                                                       option1,
   34                                                                       displayText,
   35                                                                       filter,
   36                                                                       someint.ToString(),
   37                                                                       file,
   38                                                                       seckret,
   39                                                                       commandStringDelimiter);

This is a little better now you can just change “commandStringDelimiter” to a different value when you need to change the delimiter. But it’s not verry readabel a better soluction is to do build a function that can build the string for you. This allows you to hide how it is created and keep it all in one place. Like this.

   54 public string BuildFileCommandString(params string[] options)
   55         {
   56             List<string> cStr = new List<string>();
   57             cStr.Add("Command");
   58             cStr.AddRange(options);
   59             return this.commandStringDelimiter + string.Join(this.commandStringDelimiter, cStr.ToArray());
   60         }      

You would call it like this.

   41 BuildFileCommandString(completePath,
   42                        GUID,
   43                        UID,
   44                        otherinfo,
   45                        option1,
   46                        displayText,
   47                        filter,
   48                        someint.ToString(),
   49                        file,
   50                        Seckret);

You will also notice that I used a string.Join rather then a string.Format this just makes it more readable to me.

4 comments:

Anonymous said...

Oh, How i hate it when people have bright ideas like the # sign for delimiting a file. Ritualistic suicide doesn't seem so bad for these people. That aside I do agree with you mostly on this. My only thing where I'll differentiate myself from you is that I do use String.Format over String.Join simply because if used wisely its a safe route to go and you can remove the output data formatting from the call and into the output string template such as using {0:C} for currency formatting using the current culture etc. I will say that having that string littered in code and not abstracted to either a resource file or a property is full of fail, especially given the large amount of fields being supplied. That is just screaming for some half wit code noob to come fuck it up. In short, good post, full of win.

Erin said...

The reason for not using string.formate in this case is actually the command in one case takes 10 args and in a different case takes 5.

Anonymous said...

Just out of curiosity... if one is defining their own delimiter why not use something like the Cstring delimiter? \x00
Non-typeable, Non-printable characters make the best delimiters IMHO

Erin said...

Well that delimiter has some problems when you pass a string from managed code and back on occasion. But it would have been better then # by it's self.