Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Surprising Substring behavior

Tags:

string

c#

I came across this behavior today while using the Substring method:

static void Main(string[] args) {
    string test = "123";
    for (int i = 0; true; i++) {
        try {
            Console.WriteLine("\"{0}\".Substring({1}) is \"{2}\"", test, i, test.Substring(i));
        } catch (ArgumentOutOfRangeException e) {
            Console.WriteLine("\"{0}\".Substring({1}) threw an exception.", test, i);
                break;
        }
    }
}

Output:

"123".Substring(0) is "123"
"123".Substring(1) is "23"
"123".Substring(2) is "3"
"123".Substring(3) is ""
"123".Substring(4) threw an exception.

"123".Substring(3) returns an empty string and "123".Substring(4) throws an exception. However, "123"[3] and "123"[4] are both out of bounds. This is documented on MSDN, but I'm having a hard time understanding why the Substring method is written this way. I'd expect any out-of-bounds index to either always result in an exception or always result in an empty string. Any insight?

like image 572
Pete Schlette Avatar asked Jul 28 '12 21:07

Pete Schlette


1 Answers

The internal implementation of String.Substring(startindex) is like this

public string Substring(int startIndex)
{
    return this.Substring(startIndex, this.Length - startIndex);
}

So you are asking for a string of zero characters length. (A.K.A. String.Empty) I concur with you that this is not clear on MS part, but without a better explanation I think that is better to give this result than throwing an exception.

Going deeper in the implementation of String.Substring(startIndex, length) we see this code

if (length == 0)
{
    return Empty;
}

So, because length=0 is a valid input in the second overload, we get that result also for the first one.

like image 172
Steve Avatar answered Oct 13 '22 21:10

Steve