为什么我在扩展方法中的 `char` 参数被解释为 `int`?
Why is my `char` argument in an extension method interpreted as `int`?
我为 string
.
编写了一个带有非常简单扩展方法的 .DLL 库
我的方法 - .Remove(char deletedChar)
,删除 string
中出现的所有 char
。这会重载默认的 .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
在屏幕截图上查看:
这意味着,我的 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# 实例方法在找到扩展之前被调用。
When the compiler can't find an instance method with a matching signature, it will bind to a matching extension method if one exists.
写这个helperclass,我们可以看到调用的好方法是:
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());
}
我为 string
.
我的方法 - .Remove(char deletedChar)
,删除 string
中出现的所有 char
。这会重载默认的 .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
在屏幕截图上查看:
这意味着,我的 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# 实例方法在找到扩展之前被调用。
When the compiler can't find an instance method with a matching signature, it will bind to a matching extension method if one exists.
写这个helperclass,我们可以看到调用的好方法是:
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());
}