0

I am working on my own command line arguments parser and after reading dozens of articles regarding method overloading I am still not certain if I am doing it right.

Am I getting any benefit from overloading methods this way? I know I could just write the entire thing in a single method (with default value parameters) by branching, but I'm experimenting overloads at the moment and I would like to know whether to continue on this path or not.

    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;
        }

}
Bridge
  • 29,818
  • 9
  • 60
  • 82
IneedHelp
  • 1,630
  • 1
  • 27
  • 58
  • 1
    "I know I could just write the entire thing in a single method (with default value parameters" - I'd just do that in this scenario – Marc Gravell Aug 13 '12 at 11:32
  • As I see it now it is indeed how overloads are used in general (with a default value for the parameters that are not provided). – TimVK Aug 13 '12 at 11:33
  • 2
    Well apart from optimizing OptionExists to use linq `return ParseOptions(toLowercase).Any(x=> x.StartsWith(option))` or even `return ParseOptions(toLowercase).Any(x=> x!=null && x.StartsWith(option))` – Bob Vale Aug 13 '12 at 11:33

5 Answers5

1

Yes, that's fine.

As you already know, you could also use optional parameters with default values, if your overloads only call another method with a default value (this would reduce the number of line of code).

ken2k
  • 48,145
  • 10
  • 116
  • 176
1

Yep, this is how overloads work.

But a side-node:

  • Do you need your code to be used from languages which don't support optional parameters? If so, consider including the overloads.
  • Do you have any members on your team who violently oppose optional parameters? (Sometimes it's easier to live with a decision you don't like than to argue the case.)
  • Are you confident that your defaults won't change between builds of your code, or if they might, will your callers be okay with that?

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

Community
  • 1
  • 1
SeToY
  • 5,777
  • 12
  • 54
  • 94
  • This is just my opinion but I do believe there's at least some people that agree with me here, that yes optional parameters are "good" and nice but they might also be a lesser evil, since in the long run you're going to end up with a lot of unnecessary code (read if statements) and input parameters that will mess up the code and a method that might end up being a lot larger than it needs to be. Not saying that they're not good, just saying that you should think before you start adding them and have a maximum of 1-2. – Thomas Lindvall Aug 13 '12 at 11:50
  • @ThomasLindvall: I totally agree with you, too... As always in programming, it depends on the environment and your exact plans... Only then you can tell whether to use overloads or optional parameters. – SeToY Aug 13 '12 at 11:52
1

The "problem" with optional parameters is that if the default value is changed in some future version X of your assembly A then any client assemblies C that reference A will need to be recompiled in order to "see" the change -- loading an updated version of A will cause them to call the new methods with the old default values.

If this is not a potential problem then using optional parameters is more convenient. The equivalent version that emulates optional parameters using multiple overloads does not have this issue because in that case the default value is baked into assembly A instead of into C.

Jon
  • 428,835
  • 81
  • 738
  • 806
1

I think your style of overloading is fine.

If you thought you might have loads of different parsing arguments (ToUpperCase etc) rather than have one class with lots of overloaded methods you might consider using object inheritance and have a LowerCaseParser, CamelCaseParser etc...

Neil Thompson
  • 6,356
  • 2
  • 30
  • 53
  • Your suggestion at the end sounds interesting, but I do not understand how to implement that. – IneedHelp Aug 13 '12 at 15:49
  • public class LowerCaseParser : MyParser (the LowerCaseParser inherits and extends the functionality of MyParser without you ever needing to change the MyParser code = the open/closed principle - http://www.oodesign.com/open-close-principle.html) – Neil Thompson Aug 13 '12 at 15:56
  • You might want to stick with over loaded methods for now though and revisit this later - sometimes over designing stuff is a mistake ;) – Neil Thompson Aug 13 '12 at 15:59
1

Yes that is the correct way to use overloads.

One thing to note about default parameters.

If you have two assemblies, A and B, A calls the function in B.

If you change the default in B:

using default values for parameters you need to recompile both assembly A and B for this change to take effect

using overloads you only need to recompile B.

This is because for default parameters, at compile time the compiler inserts the default values.

Bob Vale
  • 18,094
  • 1
  • 42
  • 49
  • Just so I can understand better: if we consider assembly A to be a compiled application and assembly B to be a compiled dll, if I change the a default value in one of the dll methods (let's say from 0 to 1), if I didn't use overloads, A would still call the method using the old default value 0 and not the new default 1 because 0 is hardcoded in A? – IneedHelp Aug 13 '12 at 11:58
  • @IneedHelp Yes, The value stored in assembly A is set at compile time for default values. So if you do not recompile A after changing the default in B then A will use the old default value. – Bob Vale Aug 13 '12 at 12:06
  • Thank you for your help and also for the optimizations using Linq. – IneedHelp Aug 13 '12 at 12:17