Creating range of numeric values based on array of strings Basically I have an array of strings. In this array, a range separator word might exist. For this example, I'm going to use the word to as range separator. We can assume that the range separator is not the first or last entry in the array. If we find the range separator we need to get the entry before and the entry after the separator, compare the two entries that we can assume are safe to parse as integer and find the character that differs between them. We then need to create new entries by counting up the number that is different, and return an IEnumerable&lt;string&gt; containing the new entries. We can also assume that only one character will differ between the start of the range and the end of the range.

For example, if the array contains these values:

1102
to
1602


we need to return

1202
1302
1402
1502


And here's my code:

public static IEnumerable&lt;string&gt; GetRangeSegments(string[] segments, string rangeIndicator)
{
    var rangeIndicatorIndex = Array.IndexOf(segments, rangeIndicator);
    var rangeSegments = new string[] { };

    if (rangeIndicatorIndex &lt; 0)
    {
        return rangeSegments;
    }

    var rangeStart = segments[rangeIndicatorIndex - 1];
    var rangeEnd = segments[rangeIndicatorIndex + 1];

    var startChars = rangeStart.ToCharArray();
    var endChars = rangeEnd.ToCharArray();

    if (startChars.Length != endChars.Length)
    {
        return rangeSegments;
    }

    var diffIndex = -1;

    for (var i = 0; i &lt; startChars.Length; i++)
    {
        if (startChars[i] == endChars[i])
        {
            continue;
        }

        diffIndex = i;
        break;
    }

    if (diffIndex == -1)
    {
        return rangeSegments;
    }

    var start = int.Parse(startChars[diffIndex].ToString()) + 1;
    var end = int.Parse(endChars[diffIndex].ToString());

    var numbers = Enumerable.Range(start, end - start);
    return rangeSegments.Concat(numbers.Select(number =&gt; rangeStart.Remove(diffIndex, 1).Insert(diffIndex, number.ToString())));
}
If a method returns an IEnumerable&lt;T&gt; we expect an deffered execution using the yield keyword.  

To make this happen and have a valid parameter validation we need another method which calls the method which is yielding.  

So let us add one  

public static IEnumerable&lt;string&gt; GetRangeSegments(string[] segments, string rangeIndicator)
{
    if (segments==null) { throw new ArgumentNullException(nameof(segments)); }
    if (rangeIndicator == null) { throw new ArgumentNullException(nameof(rangeIndicator)); }
    if (string.IsNullOrWhiteSpace(rangeIndicator)) { throw new ArgumentException("May not be empty.", nameof(rangeIndicator)); }

    return GetSegments(segments, rangeIndicator);
}


All the if statements will be executed and if the code comes to return it will immediately return because it knows about the yieldings in the GetSegments() method.  

Using yield makes the empty string[] rangeSegments superflous because we just yield break. If you call ToArray() on the result of these yield break you get an empty array.  

Because you can access the chars of a string by using its index you don't need ToCharArray().  

If there isn't by some mistake either rangeStart[diffIndex] or rangeEnd[diffIndex] a digit the code blows up at the call to int.Parse(). A better way would be to use int.TryParse() and if this doesn't succeed you could yield break.  

But if we e.g do int start = rangeStart[diffIndex] + 1; then the ascii value of that char will be casted to an int which we then can check if 47 &lt; start &lt; 58 and if not we yield break here.  

The return statmenet in your method is just unreadable, hence hard to maintain as well. To "replace" a single char inside a string we can just use a StringBuilder.  

Summing all up lead to  

public static IEnumerable&lt;string&gt; GetRangeSegments(string[] segments, string rangeIndicator)
{
    if (segments == null) { throw new ArgumentNullException(nameof(segments)); }
    if (rangeIndicator == null) { throw new ArgumentNullException(nameof(rangeIndicator)); }
    if (string.IsNullOrWhiteSpace(rangeIndicator)) { throw new ArgumentException("May not be empty.", nameof(rangeIndicator)); }
    return GetSegments(segments, rangeIndicator);
}

private const int ascii0 = 48;
private const int ascii9 = 57;
private static IEnumerable&lt;string&gt; GetSegments(string[] segments, string rangeIndicator)
{
    var rangeIndicatorIndex = Array.IndexOf(segments, rangeIndicator);

    if (rangeIndicatorIndex &lt; 0 || rangeIndicatorIndex == segments.Length - 1)
    {
        yield break;
    }

    var rangeStart = segments[rangeIndicatorIndex - 1];
    var rangeEnd = segments[rangeIndicatorIndex + 1];

    if (rangeStart.Length != rangeEnd.Length)
    {
        yield break;
    }

    var diffIndex = GetFirstDifferentCharPosition(rangeStart, rangeEnd);
    if (diffIndex == -1)
    {
        yield break;
    }

    var start = rangeStart[diffIndex] + 1;
    if (start &lt; ascii0 || start &gt; ascii9) { yield break; }

    var end = rangeEnd[diffIndex];
    if (end &lt; ascii0 || end &gt; ascii9) { yield break; }

    if (end &lt; start) { yield break; }

    StringBuilder sb = new StringBuilder(rangeStart);
    for (int i = start; i &lt; end; i++)
    {
        sb[diffIndex] = (char)i;
        yield return sb.ToString();
    }

}
private static int GetFirstDifferentCharPosition(string first, string second)
{
    var diffIndex = -1;

    for (var i = 0; i &lt; first.Length; i++)
    {
        if (first[i] != second[i])
        {
            diffIndex = i;
            break;
        }
    }
    return diffIndex;
}