Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compensating for the lack of 'out' parameters in async methods.

I have a class that handles all API transactions in the application I'm working on. The general outline for its methods look like this:

public static async Task<bool> APICall(int bla)
        {
            HttpResponseMessage response;
            bool res;

            // Post/GetAsync to server depending on call + other logic
            return res;
        }

What I want to do is to be able to also return the response.StatusCode to the caller, but since we are not allowed to use 'out' parameters with async methods it complicates things a bit.

I was thinking about returning a tuple containing both the bool and the response code, is there a better way to do this?

like image 594
Darajan Avatar asked Aug 08 '13 07:08

Darajan


2 Answers

I was thinking about returning a tuple containing both the bool and the response code, is there a better way to do this?

You could create a specific class to hold the results. Personally I don't really like tuples, because names like Item1 or Item2 say nothing about the values.

class APICallResult
{
    public bool Success { get; set; }
    public HttpStatusCode StatusCode { get; set; }
}

    public static async Task<APICallResult> APICall(int bla)
    {
        HttpResponseMessage response;
        bool res;

        // Post/GetAsync to server depending on call + other logic
        return new APICallResult { Success = res, StatusCode = response.StatusCode };
    }
like image 125
Thomas Levesque Avatar answered Oct 21 '22 11:10

Thomas Levesque


Use a Tuple<x, y> to return more than a value. For example, to return an int and a string:

return Tuple.Create(5, "Hello");

and the type is Tuple<int, string>

Or you could simulate the out/ref with an array... If you pass the method an array of one element, it's like passing a ref or an out (depending on who should fill the element):

MyMethod(new int[1] { 6 });

void MyMethod(int[] fakeArray)
{
    if (fakeArray == null || fakeArray.Length != 1)
    {
        throw new ArgumentException("fakeArray");
    }

    // as a `ref`
    fakeArray[0] = fakeArray[0] + 1;

    // as an `out`
    fakeArray[0] = 10;
}

Or using complex objects...

class MyReturn
{
    public string Text { get; set; }
    public int Value { get; set; }
}

MyMethod(new MyReturn());

void MyMethod(MyReturn ret)
{
    ret.Text = "Hello";
    ret.Value = 10;
}

Done...

like image 21
xanatos Avatar answered Oct 21 '22 11:10

xanatos