Listing 4.15 called DirectoryCountLines(), which counted the lines of *.cs files. However, if you want to count code in *.h/*.cpp files or in *.vb files, DirectoryCountLines() will not work. Instead, you need a method that takes the file extension, but still keeps the existing method definition so that it handles *.cs files by default.
All methods within a class must have a unique signature, and C# defines uniqueness by variation in the method name, parameter data types, or number of parameters. This does not include method return data types; defining two methods that have only a different return data type will cause a compile error. Method overloading occurs when a class has two or more methods with the same name and the parameter count and/or data types vary between the overloaded methods.
Method overloading is a type of operational polymorphism. Polymorphism occurs when the same logical operation takes on many (poly) implementations (forms) because the data varies. Calling WriteLine() and passing a format string along with some parameters is implemented differently than calling WriteLine() and specifying an integer. However, logically, to the caller, the method takes care of writing the data and it is somewhat irrelevant how the internal implementation occurs. Listing 4.16 provides an example, and Output 4.10 shows the results.
Listing 4.16. Returning All the Filenames, Given a Directory
The effect of method overloading is to provide optional ways to call the method. As demonstrated inside Main(), you can call the DirectoryCountLines() method with or without passing the directory to search and the file extension.
Notice that the parameterless implementation of DirectoryCountLines() was changed to call the single-parameter version (int DirectoryCountLines(string directory)). This is a common pattern when implementing overloaded methods. The idea is that developers implement only the core logic in one method and all the other overloaded methods will call that single method. If the core implementation changes, it needs to be modified in only one location rather than within each implementation. This pattern is especially prevalent when using method overloading to enable optional parameters.