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.:
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..