Karl Seguin

Sponsors

The Lounge

Advertisement

Images in this post missing? We recently lost them in a site migration. We're working to restore these as you read this. Should you need an image in an emergency, please contact us at imagehelp@codebetter.com
code better - use string.format
Poorly handled exceptions might speak volumes about someone's coding abilities, but it's string concatenation that's a sure bet to kill a programs readability (thus maintainability). Everyone knows that they should use StringBuilder's for better performance when concatenating a lot, but to improve maintainability, string.format is king!

On the topic of performance though, you'll be glad to know that there's also an AppendFormat method to the stringbuilder class - so readability and performance aren't exclusive concepts!

Surely, I can't be the only one that has a hard time writing and maintaining code like:
document.SelectSingleNode("/graph/data[name='" + name + "']");

When I do write code like the above, I almost always forget my closing quote or square bracket! And as things get more complicated, it becomes a flat out nightmare.

The solution is to make heavy use of string.Format. You'll never EVER see me use + (or & in VB.NET) to concatenate something to a string, and there's no reason you should either. To write the above code better, try:
document.SelectSingleNode(string.Format("/graph/data[name='{0}']", name));

Personally, even though it's a simple example, I find it a lot better - and as things get more complicated you'll be laughing as you code. But wait, there's more!  string.Format uses string formatting - so you have a lot of control over how objects are turned into strings. So you coul do
string.Format("Your score is {0:p}", student.FinalExam.Score); 
which would format the float score into a percentage.

Understanding .NET String formatting is important because (a) it'll make it so you never ask a question about how to get a date in a certain format, (b) how to get a number in a certain format and (c) it's used all over in .NET.  For example, that DataBinder.Eval() method actually accepts a 3rd parameter which is the string formatter to use.

Now, like I said earlier, you can also use AppendFormat of the StringBuilder class

StringBuilder sb = new StringBuilder();
sb.Append("<books>");
foreach(Book book in author.Books)
{
   sb.AppendFormat("<book isbn=\"{0}\">{1}</book>", book.Isbn, book.Name);
}
sb.Append("</books>");

A word of caution. String.format IS NOT a substitute for using command parameters. But dang, it is sweet for almost everything else!

Posted Mon, Apr 10 2006 3:01 PM by karl
Filed under:

[Advertisement]

Comments

Rajiv Menon wrote re: code better - use string.format
on Tue, Apr 11 2006 12:19 AM
Hey Karl,
Here's a cool article on string formatting from Kathy.
link: http://blogs.msdn.com/kathykam/archive/2006/03/29/564426.aspx
Christopher Steen wrote Link Listing - April 12, 2006
on Wed, Apr 12 2006 10:24 PM
&quot;Atlas&quot; April CTP Release [Via: Rich Ersek ]
[T-SQL] Call a stored procedure once for each row in a...
Sharbel wrote re: code better - use string.format
on Fri, Apr 21 2006 5:02 PM
Good article

String.Format() is fantastic for 2-4 concats.  Also, i recall performace tests showing StringBuilders were a waste for under 5 concats, and using String.Format() is perfectly acceptable.
-:[web caboodle]:- wrote code better - use string.format
on Fri, Apr 21 2006 10:33 PM
programer wrote re: code better - use string.format
on Sun, Apr 23 2006 12:55 AM
good article,study
GR KHAN wrote re: code better - use string.format
on Sun, Apr 23 2006 9:40 AM
Please give code that how we convert numbers into arabic language.
Thanks,
John Papa wrote re: code better - use string.format
on Sun, Apr 23 2006 11:17 AM
Good post, Karl. I generally use string.Format(...) for 3 (+/-) or less concats. Otherwise I use Stringbuilder. The plus or minus is there because I use the good ol' eyeball technique to make sure it passes the readability test :)
karl wrote re: code better - use string.format
on Sun, Apr 23 2006 11:38 AM
GR KHAN:
Using the out-of-the-box Globalization features of .NET,it's only possible to localize currency symbol, decimal separators, and other numeric symbols. I don't believe there's a straightfoward way to convert a Int32 into a localized version of the # unfortunetly (though I could be wrong).

This is the best I could find which might help you:
http://www.codeproject.com/csharp/num_to_arabic.asp
pecha wrote re: code better - use string.format
on Tue, Apr 25 2006 6:05 PM
Nice article! But few days ago I found that string.Format works very slow. Example with + .. + (see below) executes in 1 sec, with string.Format this is about 6 sec!! in VS 2005.

string userID = "ccf5acf6-2d28-4077-83d4-9fa6685057d4";
Console.WriteLine(DateTime.Now.ToLongTimeString());
for (int i = 0; i < 5000000; i++)
{
   string a = "SELECT * FROM TTT WHERE UserID = '" + userID + "' ORDER BY BBB DESC LIMIT 1";
}
Console.WriteLine(DateTime.Now.ToLongTimeString());
Console.WriteLine("---------------------------------");
Console.WriteLine(DateTime.Now.ToLongTimeString());
for (int i = 0; i < 5000000; i++)
{
   string a = String.Format("SELECT * FROM TTT WHERE UserID = '{0}' ORDER BY BBB DESC LIMIT 1", userID);
}
Console.WriteLine(DateTime.Now.ToLongTimeString());

Console.Read();
karl wrote re: code better - use string.format
on Tue, Apr 25 2006 7:25 PM
I did say you should never use string.Format in lieu of command parameters. Anyways, that point aside, I guess you should always take into account performance, but almost anyone should be willing to pay the price for a 6 second delay over 5 million iteration for varstly improved readability.

Remember, you can always use the AppendFormat method of the StringBuilder for a lot of concatenation..works just like string.Format..
pecha wrote re: code better - use string.format
on Wed, Apr 26 2006 5:09 AM
I absolutely agree with you, string.Format this is a very nice feature. I just showed small example, maybe for someone it will be interesting.
Ayende Rahien wrote re: code better - use string.format
on Sat, Apr 29 2006 11:35 AM
Pecha,
Just to note, the first version doesn't do anything, the compiler concantated in in compile time.
Scott Van Vliet wrote re: code better - use string.format
on Mon, May 8 2006 6:16 PM
I use String.Format everywhere! And infact, it uses StringBuilder under-the-hood:

public static string Format(IFormatProvider provider, string format, params object[] args)
{
     if ((format == null) || (args == null))
     {
           throw new ArgumentNullException((format == null) ? "format" : "args");
     }
     StringBuilder builder1 = new StringBuilder(format.Length + (args.Length * 8));
     builder1.AppendFormat(provider, format, args);
     return builder1.ToString();
}

Cheers.
Karl Seguin [MVP] wrote Wishlist: System.Exception constructor to support string formatting
on Mon, May 15 2006 10:27 AM
As I've indicated in the past, I'm a pretty big fan of string.Format and anything else that accepts a...
Karl Seguin [MVP] wrote Have I inherited a disaster?
on Thu, May 18 2006 5:20 PM
I hate taking over someone's bad code. The projects always go on forever and you are forced to follow...
Brian wrote re: code better - use string.format
on Wed, Jun 14 2006 6:23 PM
Is there a character limit on the target string which is being formatted?
karl wrote re: code better - use string.format
on Wed, Jun 14 2006 6:46 PM
Brian:
I'm under the strong impressions that string's in .NET have no real upper limit, other than what the OS (32 bits) imposes and whatever overhead .NET has (like the fact that all chars are unicode, so cut that in 1/2).
Brian wrote re: code better - use string.format
on Thu, Jun 15 2006 7:58 AM
Here's my trouble:

I have a little .NET Windows Forms utility that I'm working on that helps generate my C# code-behind files for an ASP.NET application.

I have three different strings I'm trying to format. The first two strings work just fine, then the 3rd string gives me this System.FormatException error:
        "Input string was not in a correct format."

//String #1: (works ok)
   string input = "\t\tprotected System.Web.UI.WebControls.CheckBoxList Q{0};";

//String #2: (works ok)
   string input = "this.Q{0}.SelectedIndexChanged += new System.EventHandler(this.Q{0}_SelectedIndexChanged);";

//String #3: (error raised)
 string input = "\tprivate void Q{0}_SelectedIndexChanged(object sender, System.EventArgs e) {";

Here's my syntax for formatting the above INPUT strings (which in my actual code are pulled out of a database into objects):

String.Format(input,param);

//the param in these cases are an Int32.ToString() which I am wanting to insert.
Brian wrote re: code better - use string.format
on Thu, Jun 15 2006 8:01 AM
I originally thought there was a character limit issue that I was encountering (because my 3rd string was actually a big block of .NET code that I was trying to format.

But even the shortened format from my above example will fail. So I don't know what I'm doing wrong.

Thanks for any and all of your help!

Brian
karl wrote re: code better - use string.format
on Thu, Jun 15 2006 8:23 AM
Brian:
The problem is that you have a { at the end of your 3rd example. { is a special character in string.Format, so it's causing it to have a hicup.

You should be able to escape the { with a double {{, ala:
string input = "\tprivate void Q{0}_SelectedIndexChanged(object sender, System.EventArgs e) {{";

but that doesn't seem to work, and I honestly can't put my finger on why this morning...

This works:
string input = "\tprivate void Q{0}_SelectedIndexChanged(object sender, System.EventArgs e) {1}";
string.Format(input, 123, "{{");

which is a little weird. I'll try to look more into it.


Paul Chu wrote re: code better - use string.format
on Mon, Sep 25 2006 1:08 AM

I was getting an error too with the embedded braces.

I added additional  parameters to insert the  braces with String.Format

{0}  --> "{"

{1}  --> "}"

function x()

{0}

alert('test');

{1}

Regards, Paul

paulchu8@gmail.com

Travis001 wrote re: code better - use string.format
on Wed, Oct 4 2006 1:27 PM

I find it somewhat funny that given the extremely slow performance of the String.Format function anyone would want to use it.

To say that as developer it is more important that we have pretty code then to have a function that takes between 4-6 times longer is pathetic. I believe that you can have nice looking code that is also concerned about performance.

Just remember that if you are writing good software you actually have customers using it and those milliseconds add up quickly.

Karl Seguin [MVP] wrote don't use string.format
on Wed, Oct 4 2006 7:41 PM

In response to my post evangilizing string.format , Travis commented that my advice was wrong, and that

Haacked wrote re: code better - use string.format
on Wed, Oct 4 2006 9:47 PM

Right.. because I heard that string.format takes around two hours to properly format a string.

DaRage wrote re: code better - use string.format
on Thu, Oct 5 2006 8:28 AM

Travis, milliseconds don't add up quickly and to believe so is mere pathetic paranoia. let the cpu do its work and let the developers to do theirs.

Tony B wrote re: code better - use string.format
on Thu, Oct 5 2006 9:06 AM

A quick Google (trying to see what the real impact on perf is)

My favorite perf guru: http://blogs.msdn.com/ricom/archive/2004/03/12/88715.aspx

DotNetKicks.com wrote Code Better - Use String.Format
on Fri, Oct 6 2006 8:47 AM

You've been kicked (a good thing) - Trackback from DotNetKicks.com

Imran Aziz wrote re: code better - use string.format
on Tue, Oct 10 2006 11:20 AM

nice one, I get into formating issues so many times specially while creating html in code, its nice to be reminded about using something that is already supported well by the language.

lb wrote re: code better - use string.format
on Tue, Oct 10 2006 7:51 PM

top article Karl!

i'm a fan of string.Format but when simply concatenating a small number of strings together, i prefer string.Concat

it's faster under the hood than string.format because it doesn't need to parse the string for arguments.

so there's four important tools here, each with their own niche:

string.format

string.concat

stringbuilder.append

stringbuilder.appendformat

that way you get performance/flexibility in just the right amount.

if you use string.format where string.Concat is more apt you do take an unwanted performance hit.

Always enjoy your stuff, Karl.

lb

Neil wrote re: code better - use string.format
on Tue, Oct 17 2006 9:56 PM

I'm having trouble converting a long (125kb...not really that long is it?) byte array (that I read from a binary file using ReadAllBytes) to a string in under 10 minutes... I've tried several methods (including BitConverter), but however I do it there's a bottleneck when building the string:/

As you say,  StringBuilder.Append works much faster than concantenating, but I still need to convert the stringbuilder back to a string at some point in order to use Contains and SubString  later on to process the file - at which point the StringBuilder.ToString takes ages!

Does anyone have any ideas?

Cheers

karl wrote re: code better - use string.format
on Wed, Oct 18 2006 6:37 AM

Would you be able to post a sample project somewhere in a zip?

Have you tried a profiler,such as RedGate's Ants or JetBrain's dotTrace? I think they both have fully functional trials...

Jay R. Wren - lazy dawg evarlast » Archive » Awesome reading wrote Jay R. Wren - lazy dawg evarlast &raquo; Archive &raquo; Awesome reading
on Thu, Nov 9 2006 3:20 PM
s wrote re: code better - use string.format
on Wed, Dec 20 2006 1:51 AM

s

anti-keseronokan » Use String.Format wrote anti-keseronokan &raquo; Use String.Format
on Thu, Dec 28 2006 9:30 AM
Scott’s Blog » String.Format is your friend wrote Scott&#8217;s Blog &raquo; String.Format is your friend
on Mon, Jan 1 2007 10:36 AM
Betta Glurpse wrote re: code better - use string.format
on Mon, Jan 15 2007 7:02 AM

I disagree. I admit that in your short one-argument example using quotes, the String.Format version is slightly more readable. But most often, I find that String.Format is less maintainable compared to concatenation with +. The main reason is that with ordinary concatenation, the arguments are kept where they are used, namely inside the string. This is good.

Consider this:

db.executeStatement(String.Format("UPDATE {0} SET owner_id={1} where owner_id is null and {2}", name, id, whereClause));

This is bad for two reasons:

1) MENTAL OVERHEAD CORRELATING PARAMETERS TO ARGUMENTS: When checking this statement, I have to remember that argument 0 is the table name, 1 is the owner id and so on until I reach the argument list and can see that there is a match. In particular, this makes it harder to decipher what poorly named variables such as "name" and "id" in the example above are being used for.

2) RENUMBERING OR DISORDER: If for some reason I need to set an additional column value in the example above, I have to either renumber the folowing arguments, or accept further mental overhead because the arguments are no longer used in the order they appear:

db.executeStatement(String.Format("UPDATE {0} SET owner_id={1}, ttime={3} where owner_id is null and {2}", name, id, whereClause, transactiontime));

karl wrote re: code better - use string.format
on Mon, Jan 15 2007 8:26 AM

Betta:

I agree that in some cases it might be worse off. But I do think that when you get into a lot of escaping, using + is a nightmare. Sticking with your not-so-good SQL example (since parameterized queries are better than both approaches)...

"insert into users (username, password, type) values ('" + name + "', '" + password + "', " + type +")"

isn't fun to write.  I forgot a couple +'s writing this out the first time and have always found it hard to read "'

again, the SQL query example isn't the best though...

Betta Glurpse wrote re: code better - use string.format
on Tue, Jan 16 2007 4:25 AM

Great to hear. There is nothing worse than people who categorically dismiss arguments that don't fit with their own preference - thankfully, you don't seem to be one of them. And yes, more readable quoting is one of the pros of using String.Format.

On another note, I absolutely agree my example isn't good database programming (with vulnerability to SQL injection being just one reason), but I think it is a decent representative "format" string. Many error messages, which probably accounts for a large portion of formatted strings, are "parameterized" in a similar fashion.

psmithphil wrote re: code better - use string.format
on Sat, Apr 28 2007 9:49 PM

I just want to thank the author for an excellent article.  This has opened up a new world for strings for me.

Sameer Alibhai wrote re: code better - use string.format
on Thu, May 31 2007 11:16 AM

I totally agree with Karl, that String.Format is much more readable.  Here is my post on why: www.sharpdeveloper.net/.../use-string.format-instead-of-chopping-strings.aspx

Jonas wrote re: code better - use string.format
on Fri, Jun 29 2007 12:23 AM

I agree on all you are saying about using

string.Format.

But I find it "ironic" that you end the post with string building XML.

What will happen when someone retreives the book; book.Name == "101 ? & Answers"

Thanks for a good article

/Jonas

paul wrote re: code better - use string.format
on Wed, Aug 22 2007 5:46 AM

hi kerl,

what is the use of string concat

karl wrote re: code better - use string.format
on Wed, Aug 22 2007 7:52 PM

Paul:

string.Concat is useful because of it's speed, but it isn't much more readable than using +.

I use string.Concat a lot when dealing with 1 (maybe 2) variables:

string cacheKey = string.Concat("userId:", userId);

Using String.Format for string formatting « Manoj Garg’s Tech Blog wrote Using String.Format for string formatting &laquo; Manoj Garg&#8217;s Tech Blog
on Tue, Apr 29 2008 4:53 AM

Pingback from  Using String.Format for string formatting &laquo; Manoj Garg&#8217;s Tech Blog

String.Format(); « namespace Programatik wrote String.Format(); &laquo; namespace Programatik
on Wed, May 14 2008 2:13 PM

Pingback from  String.Format(); &laquo; namespace Programatik

Brian Hill wrote re: code better - use string.format
on Fri, Jul 18 2008 1:44 PM

I know this blog is a little old, but I found it while researching some string formatting questions.  I’d hate to think that some junior developer would find this and think that String.Format had performance problems.  That’s just not true.  The truth is that String.Format performs better.

I'm posting here regarding Betta's comment. The truth to this is that Betta's example doesn't actually test String.Format against basic string concatenation.  Here is a quote from MSDN on System.String:

“A String is called immutable because its value cannot be modified once it has been created. Methods that appear to modify a String actually return a new String containing the modification. If it is necessary to modify the actual contents of a string-like object, use the System.Text.StringBuilder class.”

This means the even doing a “some string” + someVariable has to create a new instance of the final output.  Because the example Betta used didn’t actually change the string for each iteration, the complier is smart enough to know this and only has to execute the  line (string a = "SELECT * FROM TTT WHERE UserID = '" + userID + "' ORDER BY BBB DESC LIMIT 1";) once, instead of 5000000 times.  To really test the performance of String.Format you have to change the example to use “WHERE UserID=” + i.  This changes the string during each actual iteration.  Running that test, String.Format actually comes out quite a bit faster (on my box over ½ a second faster).  This is because String.Format is doing the same thing under the covers that StringBuilder does.

parke wrote re: code better - use string.format
on Sat, Aug 30 2008 6:59 AM

Thank you...

AnswerCage wrote re: code better - use string.format
on Wed, Sep 24 2008 9:07 AM

Thank you Brian, i've setup a test for the three Methods +,stringbuiler and string.format and you're right.

Chris wrote re: code better - use string.format
on Wed, Feb 4 2009 12:15 PM

OMG - if you're really writing XML like that you need help!

Matthew wrote re: code better - use string.format
on Fri, Jun 19 2009 5:12 AM

Really?  You love String.Format that much?  Put performance aside for a moment.  I contest that readability is not improved by String.Format, even though I am a die-hard C programmer who used to love printf().

The problem with these substitution routines is that they separate the symbol from the variable.  You're stuck seeing cryptic {0}, {1}, {2}, {3}, {4}, ... and then you only find out at the end of the statement which variables mean what.  Order is critical.  If you mess up that, then you can introduce some subtle bugs.

Really, I do think this:

               Console.WriteLine(

                   "number: " + i.ToString() + "." +

                   "number + 1: " + (i + 1).ToString() + "." +

                   "number + 2: " + (i + 2).ToString() + "."

               );

is more clear than this mess:

               Console.WriteLine(

                   String.Format(

                       "number: {0}.number + 1: {1}.number + 2: {2}.",

                       i, i + 1, i + 2

                   )

               );

Matthew wrote re: code better - use string.format
on Fri, Jun 19 2009 2:17 PM

By the way, String.Format does not have a monopoly on string formatting.  You can also specify a format for a single object to its ToString() method.  So, for instance, this:

           string s = "0x" + 16.ToString("x");

accomplishes the same thing as:

           string s = String.Format("0x{0:x}", 16);