.netresharperoverloadingstring.formatresharper-7.1

Overloaded methods give "Method with optional parameter is hidden by overload" warning in Resharper


I have a few C# apps that do logging, and the Output method has an overload to accept the message and a StreamWriter, and another overload with an additional parameter for a params array. An example of the method signatures is:

private static void Output(string message, StreamWriter writer, params object[] args) 
{..}

private static void Output(string message, StreamWriter writer) 
{..}

The question concerns Resharper that gives the following warning for these methods: "Method with optional parameter is hidden by overload".

The warning is misleading because I call the 2-param overload from inside the 3 param overload and it does not result in a recursive call, so the overload is not hidden.

I did some research on the Resharper site and there have been some tickets opened on this issue that have been closed as "will not fix".

It seems to me that this is a valid use case, since the runtime knows which overload to call. Also there are examples in the .NET framework where they use such overloads.

For example, StreamWriter.WriteLine() has overloads for the value to write, and also Format params.

Is this a valid argument, or should my methods be renamed to something like "OutputFormat" since behind the scenes they are using string.Format to build a string with the specified params?


Solution

  • As far as I see, there are two questions in your post.

    First of all, if you feel that your methods could be renamed into something more obvious; go ahead, that will improve many aspects of your code (readability, usability, etc.). The names should describe as closely as possible what they do.

    Second, about the Resharper warning:

    Recursivity using overloaded functions does not necessary imply or lead to the warning you are seeing.

    You probably know that an overloaded function is most commonly used when the parameters of a function have different types, but the function does the same thing, such as:

    private static void Print(int i) {...}
    
    private static void Print(bool b) {...}
    

    However, if a function is overloaded and if that overload has parameters of the exact same type as well as optional parameters, you most likely have a design problem.

    Basic Explanation

    If you have something like this :

    private static void Print(string message) {...}
    
    private static void Print(string message, string messageDelimiter = "===\n") {...}
    

    When you call the Print function from your class both functions will look the same: Print("my message");. The one with the optional parameter is hidden.

    Thus, you can simply merge them like this:

    private static void Print(string message, string messageDelimiter = "===\n") {...}
    

    Moreover

    You also might want to do something more clever, like giving the user access to one public function while restricting the one with the optional parameter like this:

    public static void Print(string message) {...} //< As you can see this one is public
    
    private static void Print(string message, string messageDelimiter = "===\n") {...}
    

    Even in that case, you will encounter the same problem.

    IMO, a good rule of thumb is to ask yourself a few questions:

    If you answer yes to all of them, it could be "ok" to ignore the Resharper comment and leave your code as it is.