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

时间:2012-02-10 23:22:29

标签: 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));

    }
}

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

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

P.S。我使用VS2010。

1 个答案:

答案 0 :(得分:14)

这一行:

s.Remove((char) c);

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

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