【问题标题】:Is this the right way to overload a method?这是重载方法的正确方法吗?
【发布时间】:2012-08-13 11:30:04
【问题描述】:

我正在开发自己的命令行参数解析器,在阅读了数十篇有关方法重载的文章后,我仍然不确定我是否做得对。

以这种方式重载方法对我有什么好处吗?我知道我可以通过分支在一个方法(使用默认值参数)中编写整个内容,但我目前正在尝试重载,我想知道是否继续沿着这条路走。

    public static class MyParsers
    {
        private static List<string> args;

        static MyParsers()
        {
            args = Environment.GetCommandLineArgs().ToList();
        }

        public static List<string> ParseOptions()
        {
            return ParseOptions(false);
        }

        public static List<string> ParseOptions(bool toLowercase)
        {
            // DEBUG: Change command line arguments here.
            var arguments = args;
            return !toLowercase
                       ? arguments
                       : arguments.MyExtToLower();
        }

        public static bool OptionExists(string option)
        {
            return OptionExists(option, false);
        }

        public static bool OptionExists(string option, bool toLowercase)
        {
            var list = ParseOptions(toLowercase);
            for (var i = 1; i < list.Count; i++)
            {
                if (list[i].StartsWith(option)) return true;
            }
            return false;
        }

}

【问题讨论】:

  • “我知道我可以在一个方法中编写整个内容(使用默认值参数” - 在这种情况下我会这样做
  • 正如我现在所看到的,它确实是一般如何使用重载(未提供参数的默认值)。
  • 除了优化 OptionExists 以使用 linq return ParseOptions(toLowercase).Any(x=&gt; x.StartsWith(option)) 甚至 return ParseOptions(toLowercase).Any(x=&gt; x!=null &amp;&amp; x.StartsWith(option))

标签: c# overloading


【解决方案1】:

是的,这是使用重载的正确方法。

关于默认参数的注意事项。

如果你有两个程序集,A 和 B,A 调用 B 中的函数。

如果更改 B 中的默认值:

为参数使用默认值,您需要重新编译程序集 A 和 B 才能使此更改生效

使用重载你只需要重新编译 B.

这是因为对于默认参数,编译器在编译时会插入默认值。

【讨论】:

  • 这样我可以更好地理解:如果我们将程序集 A 视为已编译的应用程序,将程序集 B 视为已编译的 dll,如果我更改其中一个 dll 方法中的默认值(假设从 0 到 1),如果我不使用重载,A 仍然会使用旧的默认值 0 而不是新的默认值 1 调用该方法,因为 0 是硬编码在 A 中的?
  • @IneedHelp 是的,存储在程序集 A 中的值在编译时设置为默认值。因此,如果您在更改 B 中的默认值后不重新编译 A,那么 A 将使用旧的默认值。
  • 感谢您的帮助以及使用 Linq 进行的优化。
【解决方案2】:

是的,没关系。

如您所知,如果您的重载仅调用具有默认值的另一个方法(这将减少代码行数),您还可以使用带有默认值的可选参数。

【讨论】:

    【解决方案3】:

    是的,这就是重载的工作原理。

    但是一个侧节点:

    • 您是否需要从不支持的语言中使用您的代码 可选参数?如果是这样,请考虑包含重载。
    • 您的团队中是否有任何成员强烈反对可选参数? (有时更容易接受一个决定 你不喜欢争论这个案子。)
    • 您是否确信您的默认值不会在代码构建之间发生变化,或者如果可能,您的调用者会接受吗?

    来源:Should you declare methods using overloads or optional parameters in C# 4.0?

    【讨论】:

    • 这只是我的观点,但我相信至少有一些人同意我的观点,是的,可选参数是“好”和好的,但它们也可能是一个较小的邪恶,因为在从长远来看,您最终会得到很多不必要的代码(读取 if 语句)和输入参数,这些代码会弄乱代码和方法,最终可能会比需要的大得多。不是说它们不好,只是说你在开始添加它们之前应该考虑一下,最多有1-2个。
    • @ThomasLindvall:我也完全同意你的看法......与编程一样,这取决于环境和你的确切计划......只有这样你才能判断是使用重载还是可选参数.
    【解决方案4】:

    带有可选参数的“问题”是,如果在您的程序集 A 的某个未来版本 X 中更改默认值,那么任何引用 A 的客户端程序集 C都需要重新编译,以便“看到”变化——加载 A 的更新版本将导致他们使用旧的默认值调用新方法。

    如果这不是潜在问题,那么使用可选参数会更方便。使用多个重载模拟可选参数的等效版本没有这个问题,因为在这种情况下,默认值被烘焙到程序集 A 而不是 C。

    【讨论】:

      【解决方案5】:

      我认为你的重载风格很好。

      如果您认为您可能有大量不同的解析参数(ToUpperCase 等) 而不是一个有很多重载方法的类,您可能会考虑使用对象继承并拥有 LowerCaseParser、CamelCaseParser 等...

      【讨论】:

      • 你最后的建议听起来很有趣,但我不明白如何实现。
      • public class LowerCaseParser : MyParser(LowerCaseParser 继承并扩展了 MyParser 的功能,您无需更改 MyParser 代码 = 开/关原则 - oodesign.com/open-close-principle.html
      • 你现在可能想坚持使用重载的方法,然后再重新审视这个 - 有时过度设计东西是一个错误;)
      猜你喜欢
      • 1970-01-01
      • 2013-09-25
      • 1970-01-01
      • 2010-10-30
      • 1970-01-01
      • 2015-05-06
      • 2014-12-17
      • 1970-01-01
      • 2015-09-11
      相关资源
      最近更新 更多