【问题标题】:Why does the string Remove() method allow a char as a parameter?为什么字符串 Remove() 方法允许 char 作为参数?
【发布时间】:2013-10-21 01:23:14
【问题描述】:

考虑这段代码:

var x = "tesx".Remove('x');

如果我运行这段代码,我会得到这个异常:

startIndex 必须小于字符串的长度。

为什么我可以将 char 而不是 int 传递给此方法? 为什么我没有收到编译错误?

为什么编译器会有这种行为?

【问题讨论】:

  • 语法:Remove(int startIndex, int length)
  • 也许人们希望这是一个重复的,就像我一样,但我找不到一个,令人惊讶的是。有人会认为这是以前问过的。

标签: c# string char


【解决方案1】:

您尝试删除声明为 char 的“x”,x 等于 120

.Remove 只接受 int 类型的 2 个参数,从字符串中删除起始和(可选)计数。

如果你传递一个字符,它将被转换为整数表示。这意味着如果您传递 'x' -> 120 大于字符串的 .Length,这就是它会抛出此错误的原因!

【讨论】:

  • 澄清一下,这是用 C# 语言做出的设计决策,它认为 char 可以隐式转换为 int(C 的残余)。
  • ... 在设计决策的帮助下,将访问检查作为重载解决方案的一部分。这使得定义私有 .Remove(Char) 毫无意义。
【解决方案2】:

Implicit conversion 允许您编译此代码,因为 char 可以转换为 int 并且不需要显式转换。这也将编译,答案将是600 (120*5) -

        char c = 'x';
        int i = c;
        int j = 5;
        int answer = i * j;

来自MSDN,隐式转换总结如下-

正如其他人所说,您可以将ReplaceRemove 与有效输入一起使用。

【讨论】:

    【解决方案3】:

    没有采用charRemove 重载,因此该字符被隐式转换为int 并且Remove 方法尝试将其用作字符串的索引,这在外部字符串。这就是为什么您会收到运行时错误而不是编译时错误说明参数类型错误的原因。

    要使用Remove 删除字符串的一部分,您首先需要找到该部分在字符串中的位置。示例:

    var x = "tesx";
    var x = x.Remove(x.IndexOf('x'), 1);
    

    这将删除字符串中第一次出现的'x'。如果可能不止一次出现,并且您想全部删除,则使用Replace 更有效:

    var x = "tesx".Replace("x", String.Empty);
    

    【讨论】:

    • 为什么我们可以传递 char 而不是 int?
    • @ShahroozJefriㇱ 当然,有一个从charint的隐式转换
    • @ShahroozJefriㇱ:某些类型可以隐式转换为其他类型,例如,当需要 int 值时,可以使用 bytechar 也可以隐式转换为 int,这在某些情况下很方便,但在这种情况下也会令人困惑。
    【解决方案4】:

    Remove 采用 int 参数作为字符串中的索引以开始删除字符,请参阅msdn。 remove 调用必须自动将 char 转换为其 ASCII 整数索引并尝试从字符串中删除该索引处的字符,而不是尝试删除字符本身。

    如果您只想删除字符串中出现 x 的任何情况,请执行以下操作:

    "testx".Replace("x",string.Empty);
    

    如果要删除字符串中 x 的第一个索引,请执行以下操作:

    var value = "testx1x2";
    var newValue = value.Remove(value.IndexOf('x'), 1);
    

    【讨论】:

    • 最初的答案建议.Replace('x', ''); 不会编译。此后已更正。
    • 不是我的反对票,但删除和替换是不同的。替换替换所有出现,这在语义上做了不同的事情
    • 我建议替换,因为从语义上看,这正是使用“x”调用 remove 时试图实现的目标。如果我用一个字符调用 remove,我希望从字符串中删除该字符的所有实例。
    【解决方案5】:

    由于您在函数中传递了一个 char 并且该值在运行时转换为 int 因此您收到运行时错误,因为运行时 char 的值大于字符串的长度。您可以尝试这样:-

    var x = "tesx";
    var s = x.Remove(x.IndexOf('x'), 1);
    

    var s = x.Replace("x",string.Empty);
    

    .Remove 将 int 作为参数。 Remove 需要两个参数。第一个是您要从字符串中的哪个位置开始。 (计数从零开始。)第二个参数是您要删除的字符数,从您指定的位置开始。

    附注:

    来自 MSDN:

    此方法(.Remove) 不会修改当前实例的值。 相反,它返回一个新字符串,其中的字符数 由 count 参数指定的已被删除。字符是 在 startIndex 指定的位置删除。

    【讨论】:

    • 删除和替换是不同的。替换替换所有出现,这在语义上做了不同的事情
    • @SriramSakthivel:- 是的,没错。还使用删除功能更新了我的答案。谢谢!
    【解决方案6】:

    您可以使用扩展方法为现有的类创建自己的方法。考虑以下示例:

    using System;
    using MyExtensions;
    
    namespace ConsoleApplication
    {
        class Program
        {
            static void Main(string[] args)
            {
                const string str1 = "tesx";
                var x = str1.RemoveByChar('x');
                Console.WriteLine(x);
                Console.ReadKey();
            }
        }
    }
    
    namespace MyExtensions
    {
        public static class StringExtensions
        {
            public static string RemoveByChar(this String str, char c)
            {
                return str.Remove(str.IndexOf(c), 1);
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-09
      • 1970-01-01
      • 2023-03-27
      相关资源
      最近更新 更多