質問

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?

役に立ちましたか?

解決

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

他のヒント

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.

In my humble opinion, the separation of concerns, if method doing different functions then we separate to two method (different method name).

But I will make one of them is private method for reflection loop, the first method will return generic type of T or just T (I maybe out of topic of Overloading, what I want to say is above example is return string, but for complex object, it can be many Overloading method to return different types, why not just return T, let the caller get object of T).

Overloading is good, depend on requirements.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top