c# - 使用扩展方法时的意外行为

标签 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(诠释)方法。

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

附言我使用 VS2010。

最佳答案

这一行:

s.Remove((char) c);

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

一般来说,我强烈建议您不要创建与扩展类型上的实例方法同名的扩展方法,特别是如果它们具有相同的名称参数数量。在不向混合中添加扩展方法的情况下,解决重载问题通常已经很困难了。不要忘记,每当无法轻易弄清楚您的代码在做什么时,一年后阅读代码的人将会有十倍的困难。

关于c# - 使用扩展方法时的意外行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9236239/

相关文章:

c++ - wchar 以一个或两个空字节结尾?

python - 解析可变长度数据

c# - 由于特殊字符,在 VB.Net 中解析 XML 失败

c# - 提高网站速度的建议?

c# - WiX 烧录 : how to change 'WixBundleManufacturer' in bootstrapper application?

c# - 如何在 C# 中连接到 mysql 数据库并模拟 SELECT、UPDATE 和 INSERT 函数

iOS - WebView 和字符串

PHP 在插入数据库之前删除空行

java - 将 String [] args 值传递给另一个类

C#加载带有嵌入图像的外部dll