为什么会这样?请遵守以下代码:
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)
- 如果可以的话,编译器将始终使用适用的实例方法而不是扩展方法。它适用于从 char
到 int
的隐式转换。这是抛出异常的方法,因为您传递给它的参数超出范围。 (事实上,您很幸运 - 在更糟糕的情况下,它会在 范围内,并返回完全出乎意料的结果。)
一般来说,我强烈建议您不要创建与扩展类型上的实例方法同名的扩展方法,特别是如果它们具有相同的名称参数数量。在不向混合中添加扩展方法的情况下,解决重载问题通常已经很困难了。不要忘记,每当您无法轻易弄清楚您的代码在做什么时,一年后阅读代码的人将会有十倍的困难。
关于c# - 使用扩展方法时的意外行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9236239/