Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Trying to map "similar looking" tuples returned from multiple functions to one variable

Say there is a library with code of this form:

 public class SomeLib
{
    public (bool WasOk, string Message) DoCheck(string fileName)
    {
        // do something here to check the file. 
        return (true, "all good");
    }

    public (bool WasOk, string Message) DoCheck(byte[] fileBytes)
    {
        // do something here to check the file as bytes 
        return (true, "all good");
    }
}

The code which uses this library looks of this form:

    int option = 1;

    SomeLib lib = new SomeLib();

    if (option == 0)
    {
        var res1 = lib.DoCheck("hello");
        MessageBox.Show(res1.WasOk + res1.Message);
    }
    else
    {
        var res2 = lib.DoCheck(new byte[] { });
        MessageBox.Show(res2.WasOk + res2.Message);
    }

What I was hoping to do, was to store the returned value from the two calls to DoCheck, to a common variable. e.g.:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

    int option = 1;

    SomeLib lib = new SomeLib();

    var res; // doesn't compile, obviously

    if (option == 0)
    {
        res = lib.DoCheck("hello");                
    }
    else
    {
        res = lib.DoCheck(new byte[] { });
    }

    MessageBox.Show(res.WasOk + res.Message);  // act on the result in the same way for both branches. 

I hope this makes sense. Is what I am trying to do possible? Let’s say that the code in the library cannot be changed.

>Solution :

var res doesn’t compile because it doesn’t have any type information. If you’re making a statement that declares a variable the compiler has to be able to work out the type somehow, either from the left or the right side:

StringBuilder sb = new StringBuilder(); //both sides, available from the dawn of time
var sb = new StringBuilder();           //for a long time
StringBuilder sb = new();               //more recently

If there isn’t a right side then the left side has to have the type info:

StringBuilder sb;

Thus for your case you need to put the type info on the left. You can even rename the members (but you don’t have to)

(bool AllGood, string Note) res;

(bool WasOk, string Message) res;

(bool, string) res;  //access the bool in res.Item1, string in res.Item2

You could do it in a one with a ternary:

var res = (option == 0) ? lib.DoCheck(hello) : lib.DoCheck(new byte[] { });

Both your methods return tuples with the same named members so your res will have res.WasOk and res.Message so it’s compiled as if it’s this:

(bool WasOk, string Message) res = ...

If your tuples coming out your methods had different names it would still compile as if it was this:

(bool, string) res = ...

And you could still access the data via Item1 and Item2


If you’re doing this ternary approach then you could deconstruct the tuple too, which also allows you to rename:

var(allGood, note) = ... ? ... : ... ;

MessageBox.Show(note);

Instead of one tuple variable where you say res.Whatever, this has created two variables like as if you’d done this:

var res = ... ? ... : ... ;
var allGood = res.WasOk;
var note = res.Message;

Plenty of options for dealing with tuples..

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading