Search code examples
c#stringsubstring

Even when a string (s1) contains 1 character, s1.Substring(1) returns an Empty string ("") - instead of IndexOutOfRangeException


I am using C# 11.0, and saw some weird behavior, that I had never seen before. But I am sure the behavior is not because of the C# version that I am using. Following is the explanation of the behavior I am seeing (the code):

char a1='a';
string s1=char.ToString(a1);
string s2 = s1.Substring(1);

After the code executes, s2 is giving me the value of string.Empty (that is ""). This is weird because, s1 has only 1 character and, s1.Substring(1) should give IndexOutOfRangeException. This is because, the definition of Substring is Substring(int startIndex). And s1.Substring(1) lies outside the bounds of s1 (like most languages, a string starts from the 0th index in C#).

I also tried it in the immediate window, and following is the result that I got:

s1
"a"
s1[0]
97 'a'
s1[1]
's1[1]' threw an exception of type 'System.IndexOutOfRangeException'
    Data: {System.Collections.ListDictionaryInternal}
    HResult: -2146233080
    HelpLink: null
    InnerException: null
    Message: "Index was outside the bounds of the array."
    Source: "System.Private.CoreLib"
    StackTrace: "   at System.ThrowHelper.ThrowIndexOutOfRangeException()\r\n   at System.String.get_Chars(Int32 index)"
    TargetSite: {Void ThrowIndexOutOfRangeException()}
s1.Substring(0)
"a"
s1.Substring(1)
""

Though s1.Substring(2) correctly gives ArgumentOutOfRangeException. But, I am perplexed to see why s1.Substring(1) returns an Empty string (that is ""). Any help would be highly appreciated. Thanks!

FYI - the answer I upvoted is explicit and makes more sense to the question I asked. Namely: [[Returns] A string that is equivalent to the substring that begins at startIndex in this instance, or Empty if startIndex is equal to the length of this instance.]


Solution

  • This behavior is actually explicitly documented in SubString's documentation (added my won bolding for emphasis):

    [Returns] A string that is equivalent to the substring that begins at startIndex in this instance, or Empty if startIndex is equal to the length of this instance.