O método .NET Substring está cheio de perigos. Desenvolvi métodos de extensão que lidam com uma grande variedade de cenários. O bom é que ele preserva o comportamento original, mas quando você adiciona um parâmetro "true" adicional, ele recorre ao método de extensão para manipular a exceção e retorna os valores mais lógicos, com base no índice e no comprimento. Por exemplo, se o comprimento for negativo e conta para trás. Você pode ver os resultados do teste com grande variedade de valores no violino em: https://dotnetfiddle.net/m1mSH9 . Isso lhe dará uma idéia clara de como ele resolve substrings.
Eu sempre adiciono esses métodos a todos os meus projetos e nunca preciso me preocupar com quebra de código, porque algo mudou e o índice é inválido. Abaixo está o código.
public static String Substring(this String val, int startIndex, bool handleIndexException)
{
if (!handleIndexException)
{ //handleIndexException is false so call the base method
return val.Substring(startIndex);
}
if (string.IsNullOrEmpty(val))
{
return val;
}
return val.Substring(startIndex < 0 ? 0 : startIndex > (val.Length - 1) ? val.Length : startIndex);
}
public static String Substring(this String val, int startIndex, int length, bool handleIndexException)
{
if (!handleIndexException)
{ //handleIndexException is false so call the base method
return val.Substring(startIndex, length);
}
if (string.IsNullOrEmpty(val))
{
return val;
}
int newfrom, newlth, instrlength = val.Length;
if (length < 0) //length is negative
{
newfrom = startIndex + length;
newlth = -1 * length;
}
else //length is positive
{
newfrom = startIndex;
newlth = length;
}
if (newfrom + newlth < 0 || newfrom > instrlength - 1)
{
return string.Empty;
}
if (newfrom < 0)
{
newlth = newfrom + newlth;
newfrom = 0;
}
return val.Substring(newfrom, Math.Min(newlth, instrlength - newfrom));
}
Eu escrevi sobre isso em maio de 2010 em: http://jagdale.blogspot.com/2010/05/substring-extension-method-that-does.html