Console word wrapping I wrote a text adventure game a while back and today I looked at it to see how I did the word wrapping (to use in a new project); I'm curious if I went about it the right way. I realize I could use an array instead of a list and remove 2 dependencies from the class but wanted some other feedback as I may have missed something obvious.

    public static string GetBorderedText(string Input, int AbsoluteLength, bool splitLines = true, int Offset = -4)
    {
        string outputString = "";

        if(Input.Length &gt; AbsoluteLength + Offset &amp;&amp; splitLines)
        {
            List&lt;string&gt; words = Input.Split(' ').ToList();
            string lineConstruction = "";

            foreach (string s in words)
            {
                if (lineConstruction.Length + s.Length + 1 &gt;= AbsoluteLength + Offset)
                {
                    outputString += "+ " + GetPaddedSubstring(lineConstruction, AbsoluteLength, Offset) + " +" + Environment.NewLine;
                    lineConstruction = "";
                    lineConstruction += s + " ";
                }
                else
                {
                    lineConstruction += s + " ";
                }
            }

            outputString += "+ " + GetPaddedSubstring(lineConstruction, AbsoluteLength, Offset) + " +";

            return outputString;
        }
        else
        {
            outputString = "+ " + GetPaddedSubstring(Input, AbsoluteLength, Offset) + " +";
            return outputString;
        }
    }


where GetPaddedSubstring  is used for getting a substring padded to a certain length.

    public static string GetPaddedSubstring(string Input, int AbsoluteLength, int Offset)
    {
        int targetLength = AbsoluteLength + Offset;
        string output = "";

        if(Input.Length &gt; targetLength)
        {
            return Input.Substring(0, targetLength);
        }
        else
        {
            output = Input.PadRight(targetLength);

            return output;
        }
    }




Lastly, for some examples. GetBorderedText can take in something like

"This room looks sturdy, but old. Lots of storage and containers. There is a door on the far side."


And return something like this.

+ This room looks sturdy, but old. Lots of storage and containers. There is a door     +
+ on the far side.                                                                     +


The + on the side are just to create a nice border within the Console window. (Hence the -4 default on Offset)
GetBorderedText(string Input, int AbsoluteLength, bool splitLines = true, int Offset = -4)



You are very inconsistent with naming parameters. Some of them are in PascalCase while only one has the correct camelCase. This makes your code look strange and unprofessional.




if (Input.Length &gt; AbsoluteLength + Offset &amp;&amp; splitLines)



Conditions like this are better stored in a variable that describes what its purpose is and split into two. Consider this:

var wrapRequired = input.Length &gt; absoluteLength + offset;
if (wrapRequired &amp;&amp; canWrap)





input.Split(' ').ToList()



You don't need to call ToList, it's already an array and can be enumerated.




foreach (string s in words)



If your collection is called words then name the item word and not s. It's very confusing when one looks at the code and wonders what that s is.




lineConstruction.Length + word.Length + 1 &gt;= absoluteLength + offset



The same here. You should name this condition propertly and especially the magic 1.



Other than this 


you should use StringBuilder for concatenating strings in loops because it's not only faster but also easier to use.
make the border as prefix &amp; suffix parameters instead of hardcoding them (or leftBorder &amp; rightBorder).
use variables with stronger names and use more of them so that they document your code.


As an example of how you can apply all these suggestions here's the new code with one new method for adding the border.

public static string CreateBorderedText(string input, int maxLength, bool canWrap = true, string prefix = "+ ", string suffix = " +")
{
    const string wordSeparator = " ";

    var lines = new List&lt;string&gt;();
    var lineBuilder = new StringBuilder();
    var borderLength = prefix.Length + suffix.Length;
    var contentLength = maxLength - borderLength;

    var wrapRequired = input.Length &gt; contentLength;
    if (wrapRequired &amp;&amp; canWrap)
    {
        var words = input.Split(' ');
        foreach (var word in words)
        {
            var projectedLength = lineBuilder.Length + word.Length + wordSeparator.Length + borderLength;
            var wrap = projectedLength &gt;= maxLength;
            if (wrap)
            {
                PadRight(lineBuilder, contentLength);
                AddBorder(lineBuilder, prefix, suffix);

                lines.Add(lineBuilder.ToString());
                lineBuilder.Clear();                
            }

            lineBuilder.Append(word).Append(wordSeparator);
        }
    }
    else
    {
        lineBuilder.Append(input);      
    }

    PadRight(lineBuilder, contentLength);
    AddBorder(lineBuilder, prefix, suffix);
    lines.Add(lineBuilder.ToString());

    return string.Join(Environment.NewLine, lines);
}


and the two helpers

private static void AddBorder(StringBuilder lineBuilder, string prefix, string suffix)
{
    lineBuilder
        .Insert(0, prefix)
        .Append(suffix);
}

private static void PadRight(StringBuilder lineBuilder, int targetLength)
{
    lineBuilder.Append(' ', targetLength - lineBuilder.Length);
}