使用扩展方法时出现意外行为

Vla*_*lad 3 c# string

为什么会这样?请遵守以下代码:

static class StringExtension
{
    public static string Remove(this string s, char c)
    {
        return s.Replace(c.ToString(), "");
    }
    public static string Remove(this string s, char[] a)
    {
        foreach (char c in a)
        {
            s = s.Remove((char)c); // <---- ArgumentOutOfRange Exception here
        }
        return s;
    }
}
class Program
{

    static void Main(string[] args)
    {
        char[] a = new char[] { '.', ',' };

        string testString = "Clean.this,string.from,periods.and,commas.";

        Console.WriteLine(testString.Remove(a));

    }
}
Run Code Online (Sandbox Code Playgroud)

当我运行此代码时,我在指示行得到一个ArgumentOutOfRange异常.事实证明,即使我有一个特定的扩展名代码Remove(this,char)和我明确地(虽然,没有理由这样)指定参数的类型,它会忽略我的扩展并尝试调用原始的Remove( int)方法.

我做错了什么或者这是C#中的错误?

PS我用的是VS2010.

Jon*_*eet 14

这一行:

s.Remove((char) c);
Run Code Online (Sandbox Code Playgroud)

正在调用string.Remove(int)- 如果可以,编译器将始终使用适用的实例方法而不是扩展方法.由于隐式转换为char,它适用int.这是抛出异常的方法,因为你传递它的参数超出了范围.(事实上​​,你很幸运 - 在更糟糕的情况下,它会范围内,并且会返回完全出乎意料的结果.)

一般来说,我强烈建议您不要创建与扩展类型上的实例方法具有相同名称的扩展方法,特别是如果它们具有相同数量的参数.一般来说,在不添加扩展方法的情况下进行重载非常困难.不要忘记,只要不能轻易弄清楚你的代码在做什么,有人在一年的时间内阅读代码将会有十倍的工作难度.

  • 只是**如何**在你读它们之前回答这些问题,我不知道.o__o但是+1,很棒的答案.:) (2认同)