tags:

views:

157

answers:

4

I have the following intentionally trivial function:

void ReplaceSome(ref string text)
{
    StringBuilder sb = new StringBuilder(text);
    sb[5] = 'a';
    text = sb.ToString();
}

It appears to be inefficient to convert this to a StringBuilder to index into and replace some of the characters only to copy it back to the ref'd param. Is it possible to index directly into the text param as an L-Value?

Or how else can I improve this?

A: 

I don't know if this is more efficient, but it works. Either way you'll have to recreate the string after each change since they're immutable.

 string test = "hello world";
 Console.WriteLine(test);

 test = test.Remove(5, 1);
 test = test.Insert(5, "z");

 Console.WriteLine(test);

Or if you want it more concise:

string test = "hello world".Remove(5, 1).Insert(5, "z");
John Sheehan
I'm genuinely curious...why did someone downmod this? Set me straight!
John Sheehan
Wasn't me, but my guess is they didn't like having two operations instead of a single char replacement. It may have eluded the downmodder that this is not possible with System.String. Or, they might vastly prefer the StringBuilder approach.
Alan
+3  A: 

C# strings are "immutable," which means that they can't be modified. If you have a string, and you want a similar but different string, you must create a new string. Using a StringBuilder as you do above is probably as easy a method as any.

Glomek
A: 
text = text.Substring(0, 4) + "a" + text.Substring(5);

Not dramatically different than your StringBuilder solution, but slightly more concise than the Remove(), Insert() answer.

Factor Mystic
+3  A: 

Armed with Reflector and the decompiled IL - On a pure LOC basis then the StringBuilder approach is definitely the most efficient. Eg tracing the IL calls that StringBuilder makes internally vs the IL calls for String::Remove and String::Insert etc.

I couldn't be bothered testing the memory overhead of each approach, but would imagine it would be in line with reflector results - the StringBuilder approach would be the best.

I think the fact the StringBuilder has a set memory size using the constructor

StringBuilder sb = new StringBuilder(text);

would help overall too.

Like others have mentioned, it would come down to readability vs efficiency...

KiwiBastard