Click here to Skip to main content
15,885,216 members
Articles / Programming Languages / C#
Tip/Trick

Extension Methods to Reverse a String and StringBuilder Object

Rate me:
Please Sign up or sign in to vote.
4.82/5 (4 votes)
1 Jan 2011CPOL2 min read 32.6K   3  
We're up to .NET 4 and MS *still* hasn't given us this simple functionality.

While writing a new article, I was fiddling around with some really old code, and stumbled across a method I wrote four years ago. It dealt with several methods for reversing a string, and it lived in a "global" class that contains a lot of little methods that makes my day-to-day development efforts a little easier.

Well, never one to let an opportunity to possibly screw up some otherwise working code go to waste, I decided to muck around by making the existing method an extension method, and adding a second one to handle StringBuilder objects. The existing string object method goes like this:

C#
public static class ExtensionMethods
{
    public static string Reverse(this string text)
    {
        if (text.Length > 1)
        {
            int pivotPos = text.Length / 2;
            for (int i = 0; i < pivotPos; i++)
            {
                text = text.Insert(text.Length - i, text.Substring(i, 1)).Remove(i, 1);
                text = text.Insert(i, text.Substring
                       (text.Length - (i + 2), 1)).Remove(text.Length - (i + 1), 1);
            }
            return text;
        }
    }
}

The whole point was to perform the operation in as little time as possible, and the best way to do that (as far as I could see) was to determine how many character swaps had to be performed (text.Length / 2), and then simply swap character on each end of the string until it met in the middle. The really cool thing about this is that it works for strings that have even AND odd lengths because in the event of an odd-length string, the middle character doesn't need to change position. In our case, the division operation rounds down to the nearest whole integer value, which is perfect for what we want to do.

For the StringBuilder object, I wanted to preserve its immutable nature, which meant I couldn't just use its ToString() method, and call the previously described method, although that's certainly a viable and easy way to accomplish the same goal. Here's the code:

C#
public static void Reverse(this StringBuilder text)
{
    if (text.Length > 1)
    {
        int pivotPos = text.Length / 2;
        for (int i = 0; i < pivotPos; i++)
        {
            int iRight     = text.Length - (i + 1);
            char rightChar = text[i];
            char leftChar  = text[iRight];
            text[i]        = leftChar;
            text[iRight]   = rightChar;
        }
    }
}

In the code above, we simply determine what positions we're at (i and iRight), retrieve the characters at those positions (rightChar, and leftChar), and put them in the appropriate location in the StringBuilder's array. (Yes, I could have done the position math in the two places I needed it, but I wanted to be able to verify (in the debugger) that the values were what I wanted.

Usage

C#
// start with text being "testing"
string text = "testing";
// the following line will cause test to be "gnitset"
text = text.Reverse();

// instantiate test with the current value of text ("gnitset")
StringBuilder test = new StringBuilder(text);
// the following line will cause test to be "testing"
test.Reverse();

I know, this ain't rocket science code, and you probably won't need it very often, but it's pretty handy to have around if you ever need to do this kind of thing.

NOTE: I want to point out that for the string method, you could always do something like this:

C#
public static string Reverse(this string text)
{
    StringBuilder temp = new StringBuilder(text);
    return temp.Reverse().ToString();
}

...which would be much more efficient in terms of memory use than doing this:

C#
public static void Reverse(this StringBuilder text)
{
    string temp = text.ToString().Reverse();
    text.Replace(text.ToString(), temp);
}

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Paddedwall Software
United States United States
I've been paid as a programmer since 1982 with experience in Pascal, and C++ (both self-taught), and began writing Windows programs in 1991 using Visual C++ and MFC. In the 2nd half of 2007, I started writing C# Windows Forms and ASP.Net applications, and have since done WPF, Silverlight, WCF, web services, and Windows services.

My weakest point is that my moments of clarity are too brief to hold a meaningful conversation that requires more than 30 seconds to complete. Thankfully, grunts of agreement are all that is required to conduct most discussions without committing to any particular belief system.

Comments and Discussions

 
-- There are no messages in this forum --