Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deconstruct tuple for pattern matching

Given a function async Task<(Boolean result, MyObject value)> TryGetAsync(), I can do

if((await TryGetAsync()) is var ret && ret.result)
{
    //use ret.value
}

But if I try to use declare the types or use deconstruction get an error "a declaration is not allowed in this context":

//declaration. error
if((await TryGetAsync()) is (Boolean result, MyObject value) ret && ret.result)
{
    //use ret.value
}

//deconstruction, also error.
if((await TryGetAsync()) is (Boolean result, MyObject value) && result)
{
    //use value
}

How can I avoid using the first option var ret in this scenario? My issue with this is that the types are not evident (which is a separate discussion).

like image 220
David S. Avatar asked Apr 04 '18 09:04

David S.


2 Answers

In C# 8.0 you can use your last option and get no error:

if((await TryGetAsync()) is (Boolean result, MyObject value) && result)
{
    //use value
}
like image 197
Rekshino Avatar answered Oct 11 '22 06:10

Rekshino


The pattern matching specification doesn't allow the value tuple notation as a valid type_pattern in the pattern matching grammar.

The tuple notation is rewritten in the compiler to use ValueTuple. So there is an option: it does work with the underlying type, ValueTuple<bool, MyObject>:

if ((await TryGetAsync()) is ValueTuple<bool, MyObject> ret && ret.Item1)

While not ideal, it could provide you with a workaround.

like image 34
Patrick Hofman Avatar answered Oct 11 '22 05:10

Patrick Hofman