C#: most readable string concatenation. best practice [duplicate] - c#

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
How should I concatenate strings?
There are several ways to concat strings in everyday tasks when performance is not important.
result = a + ":" + b
result = string.Concat(a, ":", c)
result = string.Format("{0}:{1}", a, b);
StringBuilder approach
... ?
what do you prefer and why if efficiency doesn't matter but you want to keep the code most readable for your taste?

It depends on the use. When you just want to concat two strings, using a + b is just much more readable than string.Format("{0}{1}", a, b). However, it is getting more complex, I prefer using string.Format. Compare this:
string x = string.Format("-{0}- ({1})", a, b);
against:
string x = "-" + a + "- (" + b + ")";
I think that in most cases it is very easy to spot the most readable way to do things. In the cases where it is debatable which one is more readable, just pick one, because your boss isn't paying for these pointless discussions ;-)

string.Format for me, but in practice I use whichever is fit for purpose, taking into account performance and readability.
If it was two variables I'd use.
string.Concat(str1, str2);
If it contained a constant or something that requires formatting then.
string.Format("{0} + {1} = {2}", x, y, x + y);
Or for something like an SQL query
string SqlQuery = "SELECT col1, col2, col3, col4" +
"FROM table t " +
"WHERE col1 = 1";
And string builder when performance matters.

String.Format(...) is slowest.
For simple concatenations which don't take place in a loop, use String.Concat(...) or the + operator, which translate to the same under the hood, afaik. What is more readable is very subjective.
Using a StringBuilder for simple concatenations is over-the-top for simple concatenations as well and has most likely too much overhead. I'd only use it in a loop.

For something like this (which I'm guessing is being sent to the UI), I would definitely prefer String.Format. It allows the string to be internationalized easy; you can grep for calls to String.Format and replace them with your translating format.

My personal preference is:
I find the + approach the most readable and only use Format() or a StringBuilder if there is a good reason (i18n, performance etc) for it. I (almost) never use Concat.
I think I find the + approach easier to read than Format() simply because I don't have to skip ahead to the end to see what variables are put into in the {} place-holders. And if the place-holders aren't in numeric order, it gets even harder to read imo.
But I guess for larger projects it makes sense to simply enforce using Format by a style guide just in case the code might be (re-)used in a project requiring i18n later on.

string.Format
for few concats. for more I use
StringBuilder approach
even if performance is not important. there is a team agreement I have to follow

I prefer String.Format for small strings, and StringBuilder for larger ones. My main reason is readability. It's a lot more readable to me to use String.Format (or StringBuilder.AppendFormat()), but I have to admit that that is just personal preference.
For really big text generation, you might want to consider using the new (VS2010) T4 Preprocessed Templates - they are really nice.
Also, if you're ever in VB.NET, I like the XML literal technique Kathleen Dollard talked about in episode 152 of hanselminutes.

Prefer to use:
String.Concat for simple concatenations like String.Concat("foo", bar);
String.Format for complex formatting like String.Format("{1}", url, text);
StringBuilder for massive concatenations like:
var sb = new StringBuilder();
sb.AppendLine("function fooBar() {");
sp.AppendLine(String.Join(Environment.NewLine, blah));
sp.AppendLine("}");
page.RegisterClientScript(page.GetType(), sb.ToString());
Prefer to avoid "foo" + "bar" (as well as if (foo == "bar"). And especially String.Format("{0}{1}", foo, bar) and
throw new Exception("This code was" +
"written by developer with" +
"13\" monitor");

Related

Building up strings from variables by neither using + nor StringBuilder

Assume we have
string one = "1";
string two = "2";
string three = "3";
And we want to get the result string
result = "1, 2, 3"
by building it from the above three variables.
I know I can do it like this
result = one + ", " + two + ", " + three;
but as far as I understand, then a lot of strings are generated and thrown away again (first 1, then 1,, then 1, 2, then 1, 2,, then 1, 2, 3). I know I can use a StringBuilder to prevent creating new strings all the time, but this is also not what I am looking for.
In my case, I know from the start how the string will look, I only need to put references of the variables into the result string.
I know I have seen a syntax before (C#). I think it looks a bit like this:
result = "{0}, {1}, {2}", one, two, three
Questions:
What is the syntax?
What is the correct name for putting a string together from pieces when the pattern is known? I assume there is a more specific word than "concatenate". In my understanding, "concatenate" is something you want to do at runtime, when you don't know in the beginning which or how many strings are to be connected.
- Is there a difference in performance or memory usage compared to using a StringBuilder? (see https://stackoverflow.com/a/299541/5333340 - it seems string.Concat is faster.)
Here is the string.Join approach. This avoids the redundant inserting of the seperator compared to your required String.Format
string one = "1";
string two = "2";
string three = "3";
string result = string.Join(", ", one, two, three);
in addition to string.join and string.format, you could also use interpolated strings which looks cleaner than string.format in many scenarios - e.g.
result = $"{one}, {two}, {three}";
What is the syntax?
var result = string.Format("{0}, {1}, {2}", one, two, three);
or (C# 6.0 string interpolation, which is just syntactic sugar for string.Format)
var result = $"{one}, {two}, {three}";
What is the correct name for putting a string together from pieces when the pattern is known? I assume there is a more specific word than "concatenate". In my understanding, "concatenate" is something you want to do at runtime, when you don't know in the beginning which or how many strings are to be connected.
String formatting or string interpolation.
Is there a difference in performance or memory usage compared to using a StringBuilder?
As of .NET 4.0, string.Format uses a cached StringBuilder internally, so the performance difference is minimal. For very large and/or very many strings, using a raw StringBuilder will be fastest, but for most cases, string.Format will be good enough in terms of performance, and a lot more readable.
The syntax you are looking for is
result = String.Format("{0}, {1}, {2}", one, two, three);

String Concatenation Best Practices

Trying to determine if it's a better practice to use string.Format in place of concatenating strings and if so, why is this? Also, are their advantages/disadvantages to one or the other that I should be aware of?
This:
string foo = "I" + " am " + " a " + " string.";
or:
string bar = string.Format("{0} am a {1}.", "I", "string");
Obviously oversimplified examples, just wanting to be clear.
The "best practice" should be the thing that makes your code the most readable and maintanable. The performance difference between concatenating strings versus using string.Format versus using a StringBuilder is so small that it's essentially irrelevant.
Assuming the first method was not optimized at compile time, because strings are immutable it will create many intermediate strings. It'll work from left to right so there will first be "I am ", then "I am a ", and finally "I am a string." which is stored in foo.
String.format will not make intermediate strings. To my understanding it does all the manipulation in a char[] which is then made immutable by being made a String.

Is this c# return statement good/bad in terms of performance?

My static method returns the following concatenated string like this
return (Sb.ToString() + " " + ds.Tables[1].Rows[0].ItemArray[0].ToString() + " " + ds.Tables[2].Rows[0].ItemArray[0].ToString());
Is this a good/bad practise or should i use stringbuilder for it....
String concatenation in a single shot will be faster than using a StringBuilder - although if Sb is already a StringBuilder, it might make sense to append to that instead (assuming it's a local variable). Assuming this is actually data which has come from a database, the time taken to fetch it is going to vastly exceed the string concatenation here anyway.
Note that you don't need all these calls to ToString() - this would do just as well:
return (Sb + " " + ds.Tables[1].Rows[0].ItemArray[0] + " " +
ds.Tables[2].Rows[0].ItemArray[0]);
Here's the equivalent using the existing builder:
return Sb.Append(" ")
.Append(ds.Tables[1].Rows[0].ItemArray[0])
.Append(" ")
.Append(ds.Tables[2].Rows[0].ItemArray[0])
.ToString();
This might be slightly faster - it will depend on various things. Personally I'd probably use the concatenation version anyway, as it's slightly simpler IMO. I highly doubt that you'd see much difference in performance. Note that this is a bit of a special case, as you've already got a StringBuilder; in the general case of concatenating a set of items where they can all be specified in one compile-time expression, concatenation can be faster as a single method call can provide all the required information.
I have a page on StringBuilder vs string concatenation if you want more details and guidelines.
I think this is more readable:
return String.Format("{0} {1} {2}",
Sb,
ds.Tables[1].Rows[0].ItemArray[0],
ds.Tables[2].Rows[0].ItemArray[0]);
About concatenating strings or using StringBuilder:
Concatenating Strings Efficiently
StringBuilder and String Concatenation
If you're calling this in a tight loop, you'll be probably be better off using StringBuilder (but this piece should be profiled nevertheless). Otherwise, concatenation is perfectly fine. I would change it, however, to String.Format() for maintainability/readability reasons.

Concerns about SQL Server 2008 Full Text Search

I have built a T-SQL query like this:
DECLARE #search nvarchar(1000) = 'FORMSOF(INFLECTIONAL,hills) AND FORMSOF(INFLECTIONAL,print) AND FORMSOF(INFLECTIONAL,emergency)'
SELECT * FROM Tickets
WHERE ID IN (
-- unioned subqueries using CONTAINSTABLE
...
)
The GUI for this search will be an aspx page with a single textbox where the user can search.
I plan to somehow construct the search term to be like the example above (#search).
I have some concerns, though:
Is the example search term above the best or only way to include the inflections of all words in the search?
Should I separate the words and construct the search term in C# or T-SQL. I tend to lean toward C# for decisions/looping/construction, but I want your opinion.
I hate building SQL dynamically because of the risk of injection. How can I guard against this?
Should I use FREETEXTTABLE instead? Is there a way to make FREETEXT look for ALL words instead of ANY?
In general, how else would you do this?
I recently used Full-Text Search, so I'll try to answer some of your questions.
• "I hate building sql dynamically because of the risk of injection. How can I guard against this?"
I used a sanitize method like this:
static string SanitizeInput(string searchPhrase)
{
if (searchPhrase.Length > 200)
searchPhrase = searchPhrase.Substring(0, 200);
searchPhrase = searchPhrase.Replace(";", " ");
searchPhrase = searchPhrase.Replace("'", " ");
searchPhrase = searchPhrase.Replace("--", " ");
searchPhrase = searchPhrase.Replace("/*", " ");
searchPhrase = searchPhrase.Replace("*/", " ");
searchPhrase = searchPhrase.Replace("xp_", " ");
return searchPhrase;
}
• Should I use FREETEXTTABLE instead? Is there a way to make FREETEXT look for ALL words instead of ANY?
I did use FREETEXTTABLE, but I needed any of the words. As much as I've read about it (and I've read quite a bit), you have to use CONTAINSTABLE to search for ALL words, or different combinations. FREETEXTTABLE seems to be the lighter solution, but not the one to pick when you want deeper customizations.
Dan, I like your SanitizeInput method. I refactored it to make it more compact and enhance performance a little.
static string SanitizeInput(string searchPhrase, int maxLength)
{
Regex r = new Regex(#";|'|--|xp_|/\*|\*/", RegexOptions.Compiled);
return r.Replace(searchPhrase.Substring(0, searchPhrase.Length > maxLength ? maxLength : searchPhrase.Length), " ");
}
static string SanitizeInput(string searchPhrase)
{
const int MAX_SEARCH_PHRASE_LENGTH = 200;
return SanitizeInput(searchPhrase, MAX_SEARCH_PHRASE_LENGTH);
}
I agree that FreeTextTable is too lightweight of a solution.
In your example, you have the #search variable already defined. As a rule of thumb, you shouldn't include dynamically concatenated text into raw SQL, due to the risk of injection. However, you can of course set the value of #search in the calling command object from your application. This completely negates the risk of injection attacks.
I would recommend construction of the search term in C#; passing the final search term in as a parameter like already mentioned.
As far as I recall, FREETEXTTABLE uses word breakers to completely decompose the search terms into their individual components. However, the FREETEXTTABLE operator automatically decomposes words into inflectional equivalents also, so you won't have to construct a complex CONTAINSTABLE operator if you decide to use it.
You could INNER JOIN the results of multiple FREETEXTTABLE queries to produce an equivalent AND result.
All of our searches are on columns in the database that have predefined valid characters.
Our search algorithm incorporates this with a regex that only allows these predefined characters. Because of this escaping in the search string is not needed. Our regex weeds out any injection attempts in the web code (asp & aspx). For standard comments from the users, we use escaping that changes all characters that may be used for harm in SQL, ASP, ASPX, & Javascript.
The TransStar site http://latranstar.tann.com/ is using an extended form of Soundex to search for street names, addresses and cities anywhere in Southern California. The Soundex by itself eliminates any need for anti-injection code since it operates only on alpha characters.

List of strings to one string

Lets say you have a:
List<string> los = new List<string>();
In this crazy functional world we live in these days which one of these would be best for creating one string by concatenating these:
String.Join(String.Empty, los.ToArray());
StringBuilder builder = new StringBuilder();
los.ForEach(s => builder.Append(s));
string disp = los.Aggregate<string>((a, b) => a + b);
or Plain old StringBuilder foreach
OR is there a better way?
I would go with option A:
String.Join(String.Empty, los.ToArray());
My reasoning is because the Join method was written for that purpose. In fact if you look at Reflector, you'll see that unsafe code was used to really optimize it. The other two also WORK, but I think the Join function was written for this purpose, and I would guess, the most efficient. I could be wrong though...
As per #Nuri YILMAZ without .ToArray(), but this is .NET 4+:
String.Join(String.Empty, los);
string.Concat(los.ToArray());
If you just want to concatenate the strings then use string.Concat() instead of string.Join().
If you use .net 4.0 you can use a sorter way:
String.Join<string>(String.Empty, los);
String.Join() is implemented quite fast, and as you already have a collection of the strings in question, is probably the best choice. Above all, it shouts "I'm joining a list of strings!" Always nice.
los.Aggregate((current, next) => current + "," + next);
My vote is string.Join
No need for lambda evaluations and temporary functions to be created, fewer function calls, less stack pushing and popping.

Categories

Resources