Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use string.Substring(char, char) instead string.Substring(int, int)?

I made the extension method that returns a string between leftChar and rightChar:

    public static string Substring(this string This, char leftChar, char rightChar)
        {
            int i_left = This.IndexOf(leftChar);
            if (i_left >= 0)
            {
                int i_right = This.IndexOf(rightChar, i_left);
                if (i_right >= i_left)
                {
                    return This.Substring(i_left + 1, i_right - i_left - 1);
                }
            }
            return null;
        }

When I invoke it up like this:

    string str = "M(234:342);".Substring('(', ')');

I get the exception:

System.ArgumentOutOfRangeException: startIndex не может быть больше, чем длина строки. Имя параметра: startIndex в System.String.Substring(Int32 startIndex, Int32 length)

The namespace of the extension method and the invoking code is correct. IntelliSense suggest me 3 extension methods (two basic and one mine).

(extension) string string.Substring(char leftChar, char rightChar)

It is clear that string.Substring(int startIndex, int Length) overlaps with my extension method because the compiler casts char to int automaticaly.

Is there a way to force the compiler not to do the cast char to int?


  • If I rename the extension method (like Substring2) all works.
  • If I change chars to params char[], it does not work, if I invoke it like params, but of course works like array.
  • If I delete the extension method, "M(234:342);".Substring('(', ')') does not throw any compilation error, but still throw the exception.
  • If I change chars to strings in the extension method it also works. This is my current favorite solution for this issue - to combine my Substring(char, char) with Substring(string, string) with checking lengths of input strings.
like image 418
AlexThunder Avatar asked Jul 05 '19 07:07

AlexThunder


1 Answers

Is there a way to force the interpreter not to do the cast char to int?

No. When it encounters a method invocation executed against a target expression, the compiler first checks whether any instance methods on the target's declared type are compatible with the arguments. It only looks for extension methods if there are no compatible methods.

In your case, the regular string.Substring(int, int) method is compatible with arguments (char, char) because of the implicit conversion from char to int.

The simplest solution is to rename your extension method - something like SubstringBetween perhaps.

like image 166
Jon Skeet Avatar answered Oct 01 '22 07:10

Jon Skeet