Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to overload a method when all you want to change is the return type

Since return type can't be used to disambiguate methods what is the cleanest/best way to overload a method when all you want to change is the return type? Below is some sample code;

public static string Get(string url, Guid id, bool logResponse = true, bool baseKey = false)
{
     Tuple<string, int> response = Get(url, id, true, logResponse, baseKey);

     if (response.Item2 > 399)
        return null;
     return response.Item1;
}


public static Tuple<string, int> Get(string url, Guid id, bool returnStatus, bool logResponse = true, bool baseKey = false)
{
    // leaving out lots of code in this method, you should be able to get the point without it
    int http_status;  
    string response = CallApi(url, key, "GET", out http_status);

    return new Tuple<string, int>(response, http_status);
}

The above code works however I have an additional param ( returnStatus ) that serves no purpose, it's only there so the compiler can tell the difference between the two methods. Is there a better way to do this or am I just stuck adding useless parameters?

like image 473
evanmcdonnal Avatar asked Dec 16 '22 07:12

evanmcdonnal


2 Answers

Change name of method, e.g.

string Get(string url, Guid id, bool logResponse)
Tuple<string, int> GetWithStatus(string url, Guid id, bool logResponse)

Main goal of programming is not to tell difference to compiler, but to tell difference to developers which will read your code. Another options is return status as out parameter:

string Get(string url, Guid id, bool logResponse, out int status)

I do not like out parameters very much, but I like tuples even less - what will tell name Item2 to developer which uses your method? Is it status, or retries count, or maybe response length? Neither method name, nor return type cannot say what is it.

So, even for first case with renamed method I'd also changed return type to something like

public class ServerResponse
{
    public string Content { get; set; }
    public HttpStatusCode Status { get; set; } // enum

    // use this in first method to check if request succeed
    public bool IsError
    {
       get { return (int)Status > 399; }
    }
}
like image 93
Sergey Berezovskiy Avatar answered Dec 18 '22 10:12

Sergey Berezovskiy


I see three options.

  1. Return object and disambiguate in your calling method.
  2. Make the method a generic, then detect the desired type using reflection.
  3. Rename the method.

I'd choose #3. Make them "GetOne" and "GetTuple" and you'll be all set.

like image 24
roufamatic Avatar answered Dec 18 '22 10:12

roufamatic