【问题标题】:Is there a sweet, efficient way to call the same method twice with two different arguments?有没有一种甜蜜、有效的方法可以用两个不同的参数两次调用同一个方法?
【发布时间】:2010-09-24 09:34:33
【问题描述】:

比如说我有以下字符串:

var testString = "你好,世界";

我想调用以下方法:

var newString = testString.Replace("Hello", "").Replace("world", "");

是否有一些代码结构可以简化这一点,这样我只需要指定一次 Replace 方法,并且可以指定一堆参数一次性传递给它吗?

【问题讨论】:

    标签: c# arrays parameters methods call


    【解决方案1】:

    我不知道这是否更甜,但你可以这样做:

    string inputString = "Hello, world";
    string newString = new[] { "Hello", "world" }.Aggregate(inputString, (result, replace) => result.Replace(replace, ""));
    

    这将以输入字符串作为种子开始,并使用每个替换字符串运行函数。

    理解 Aggregate 函数的一个更好的例子可能是:

    List<Payment> payments = ...;
    double newDebt = payments.Aggregate(oldDebt, (debt, payment) => debt - payment.Amount);
    

    【讨论】:

      【解决方案2】:

      我看到这些模式存在几个缺陷 - 首先,不可变的字符串多次调用 replace 或在循环中可能很糟糕,尤其是当您的输入字符串很大时。如果你一心想要调用 replace,那么至少使用 StringBuilder 类中的 Replace 方法。

      【讨论】:

        【解决方案3】:

        在某些语言(例如 python)中,存在 reduce 或 fold 函数的概念 - 这是一种表示列表中所有元素的循环的函数式方式。

        使用reduce你可以写出这样的东西

        return reduce(lambda a, x: a.Replace(x, ''), ['hello', 'world'], 初始)

        相同 a = 初始 对于 ['hello', 'world'] 中的 x: a = a.替换(x,'') 返回一个

        在python中你也可以发音为

        减少(str.replace,['hello','world'],初始)。

        当然这是否更简单完全是另一个问题 - 但很多人当然喜欢编写这样的代码。

        【讨论】:

          【解决方案4】:

          你可以用正则表达式来做,比如:

          var newString = Regex.Replace(testString, "Hello|world", "");
          

          如果您想从一个序列以编程方式构建正则表达式,它会是这样的:

          var stringsToReplace = new[] { "Hello", "world" };
          var regexParts = stringsToReplace.Select(Regex.Escape);
          var regexText = string.Join("|", regexParts.ToArray());
          

          【讨论】:

            【解决方案5】:

            很多人说你应该使用 IEnumerable 和 List 和 Arrays 等,虽然这完全“可以”,但如果我是你,我宁愿在 C# 中使用 params 关键字。如果我要实现这样的事情 - 我可能不会关心像你的双 Replace 方法调用这样简单的事情......

            【讨论】:

              【解决方案6】:

              另一个提高可读性的选择是添加新行和适当的缩进(这对我来说是更好的选择):

              var newString = testString.Replace("Hello", "")
                                        .Replace("world", "")
                                        .Replace("and", "")
                                        .Replace("something", "")
                                        .Replace("else","");
              

              【讨论】:

                【解决方案7】:

                您可以创建自己的 Replace 扩展方法,该方法采用 IEnumberable 参数。然后循环遍历迭代器并使用 replace 方法。

                那么你可以这样称呼它 .Replace(new string[] {"Matt", "Joanne", "Robert"}, "")

                我认为应该这样做

                public static string Replace(this string s, IEnumerable<string> strings, string replacementstring)
                {
                    foreach (var s1 in strings)
                    {
                        s = s.Replace(s1, replacementstring);
                    }
                
                    return s;
                }
                

                【讨论】:

                • 为什么要使用 IEnumberable?而不仅仅是使用 params 关键字?
                • 它有效,但对我来说感觉有点不确定。只有当我不得不在很多地方一次性替换很多值时,我才会使用它。不过,我真的想不出一个合适的例子。
                • @Ray:看到这个方法的所有其他参数都是字符串,当你使用 params string[] 字符串时可能会造成混淆。
                【解决方案8】:

                正如其他帖子中所述,有很多方法。

                但通常甜蜜=高效(=可维护)=简单。最好不要尝试,除非您描述问题的上下文有某些原因。

                【讨论】:

                  【解决方案9】:

                  创建一个函数,将StringDictionary(String, String) 传递给该函数。遍历 Dictionary 和 InputString.Replace(DictionaryEntry.Key, DictionaryEntry.Value) 中的每个项目。返回具有替换值的字符串。

                  但如果只有 2 次,我只会做 .Replace.Replace...

                  【讨论】:

                    【解决方案10】:

                    您提出的任何结构都可能比您原来的帖子更复杂。如果您有很多不同的参数要传递,您可以构建这些参数的向量并在执行调用时对其进行迭代。但是话又说回来,对于您当前的示例,修改后的版本会更长,编写起来也更复杂。两次只是重复率太小了。

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2010-09-28
                      • 2012-07-08
                      • 2019-09-27
                      • 1970-01-01
                      • 2020-11-08
                      相关资源
                      最近更新 更多