c# - 为什么扩展方法中的 `char` 参数被解释为 `int` ?

标签 c# dll extension-methods

我为 string 编写了一个带有非常简单的扩展方法的 .DLL 库。

我的方法 - .Remove(char deletedChar) 删除 char 中所有出现的 string 。这会重载默认的 .Remove(int startIndex) 方法。但是,当我想使用它时,尽管我将 .Remove(int startIndex) 作为参数,但仍会调用 char,而不是我的方法。

我的意思是,给出这段代码:

string Test = "12-34-56-78-90-123-456-789-0123-4567-89012-34567-890123-456789-000000";
MessageBox.Show(Test.Remove('-'));

我的预期结果是:

1234567890123456789012345678901234567890123456789000000

然而,实际结果是:

12-34-56-78-90-123-456-789-0123-4567-89012-34

在屏幕截图中查看:

ss

这意味着,我的 char '-' 被解释为其 ASCII 值 (45),这是删除字符串的起始索引。

为什么会发生这种情况?即使将 char 转换为 char (即 (char)'-' )也无法修复它。我知道我可以简单地重命名扩展方法,但我仍然不明白为什么会发生这种情况。有人可以解释这种现象或指出解释它的文档吗?

粘贴我的扩展方法,以防有人想要使用它:

    /// <summary>
    /// Removes all occurences of specified char.
    /// </summary>
    /// <param name="str"></param>
    /// <param name="deletedChar">The char you want to remove.</param>
    /// <returns>string without the specified char.</returns>
    public static string Remove(this string str, char deletedChar)
    {
        for (int i = 0; i < str.Length; i++)
        {
            if (str[i] == deletedChar)
            {
                str = str.Remove(i, 1);
                i--;
            }
        }
        return str;
    }

最佳答案

如果找到扩展,C# 实例方法将在扩展之前调用。

来自documentation :

When the compiler can't find an instance method with a matching signature, it will bind to a matching extension method if one exists.

编写这个辅助类,我们可以看到调用了好的方法:

public static class StringHelper
{
  public static string MyRemove(this string str, int index)
  {
    return "remove at index";
  }
  public static string MyRemove(this string str, char code)
  {
    return "remove all chars";
  }
}

测试

Console.WriteLine("".MyRemove(1));
Console.WriteLine("".MyRemove('a'));

输出

remove at index
remove all chars

因此解决方案是使用专用方法的名称:

public static class StringHelper
{
  public static string RemoveAll(this string str, char deletedChar)
  {
    for ( int i = 0; i < str.Length; i++ )
    {
      if ( str[i] == deletedChar )
      {
        str = str.Remove(i, 1);
        i--;
      }
    }
    return str;
  }
}

因此设计和使用更加清晰和干净,也更容易表达,而参数的类型告诉我们要删除什么。

但是这样的方法并未经过优化,例如可以替换为:

public static string RemoveAll(this string str, char code)
{
  return str.Replace(code.ToString(), "");
}

或者通过这个更好:

using System.Text;

public static string RemoveAll(this string str, char code)
{
  var builder = new StringBuilder();
  foreach ( char c in str )
    if ( c != code )
      builder.Append(c);
  return builder.ToString();
}

或者使用 Linq,但可能不如以前优化:

using System.Linq;

public static string RemoveAll(this string str, char code)
{
  return new string(str.Where(c => c != code).ToArray());
}

关于c# - 为什么扩展方法中的 `char` 参数被解释为 `int` ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67546438/

相关文章:

c# - 程序集中的嵌入资源位置

c# - 在 C# 中序列化/编码简单对象以通过网络发送,供非托管 C++ 应用程序读取

c# - 从 View 模型更新模型

c++ - 如何使用另一个 DLL 为 Qt 制作第三方插件?

c# - 扩展Datarow扩展方法

c# - 如何在 C# 中创建扩展?

C# 关于 lambda 表达式的解释

c++ - 没有 DllRegisterServer 等的 COM dll

c++ - 如何从 dll 正确返回 std::list

ios - 我可以只创建一个 Apple Watch 扩展(没有 UI 或 App for Watch)吗?