Yes, tuples are great, especially as a replacement for out string foo
and I use them primarily for returning multiple things for rather low level methods when out
or a C# class/struct is just overkill. The fact that the tuple parameters can be named was a huge advancement, rather than having to use Item1
, Item2
, etc. That said, I use them judiciously and always ask myself, if I'm using a tuple here, is that the right approach or am I compensating for a possibly bad "design." For example (this from code I have in a library):
public (HttpStatusCode status, string content) Get(string url, Dictionary headers = null)
{
var client = RestClientFactory();
var request = new RestRequest(url, Method.Get);
headers?.ForEach(kvp => request.AddHeader(kvp.Key, kvp.Value));
RestResponse response = client.Execute(request);
return (response.StatusCode, response.Content);
}
Why am I parsing out the status code and content instead of just returning the response
object? One answer is that returning response
may probably require a using RestSharp
and even a reference to the RestSharp package in the caller project. OK, maybe that's a defensible argument, maybe not. After using this library of mine (REST is just one small part of this library) I'm not that thrilled with my initial wrapper implementation. But because I started this "pattern", it continues, like:
public (T item, HttpStatusCode status, string content) Get(string url, Dictionary headers = null) where T : new()
{
var client = RestClientFactory();
var request = new RestRequest(url, Method.Get);
headers?.ForEach(kvp => request.AddHeader(kvp.Key, kvp.Value));
RestResponse response = client.Execute(request);
T ret = TryDeserialize(response);
return (ret, response.StatusCode, response.Content);
}
And this illustrates mashing together various potentially bad implementation/designs. The tuple now returns three things, and the TryDeserialize
catches exceptions silently, returning a null for T item
, and what if I want the actual deserialization exception? And now that I look at that code again after a couple years, what's with that AddHeader
loop when there's a perfectly