Using `is` operator with value type tuples gives error
Asked Answered
R

1

23

I am trying to check if an object variable is (int, int) and if so I will use the casted variable so I have tried the codes below:

//this one gives the error
public void MyMethodWithIs(object val)
{
    if(val is (int id, int name) pair)
    {
        ConsoleWriteLine($"{pair.id}, {pair.name}");
    }
}

//This one works
public void MyMethodWithAs(object val)
{
    var pair = val as (int id, int name)?;
    if(pair!=null)
    {
        ConsoleWriteLine($"{pair.id}, {pair.name}");
    }
}

The MyMethodWithIs method gives the error below in the editor:

No suitable deconstruct instance or extension method was found for type

My Question

Why one works fine but the other gives an error at all? I think MyMethodWithIs more readable and suitable to use for my case but I can't use it due to giving an error.

Reorganization answered 12/5, 2019 at 20:22 Comment(3)
AFAIK value tuples don't store item name information, so there is probably no way to check if the items are id and name. I am guessing it might work without names if (val is (int, int) pair)Coan
@Coan I also tried it, but the same error appears.Reorganization
if (val is ValueTuple<int,string> pair) works though. Somewhat related: #44706998Sikata
B
23

Using C# 8's pattern matching capabilities, you can write this:

if (val is (int id, int name))
{
    Console.WriteLine($"id: {id}; name: {name}");
}

However this boxes id and name, which is surprising. There's a proposal to optimize this.

Below C# 8, you can write this:

if (val is ValueTuple<int, int> pair)
{
    Console.WriteLine($"id: {pair.Item1}; name: {pair.Item2}");
}

You can of course make it a bit clearer:

if (val is ValueTuple<int, int> pair)
{
    var (id, name) = pair;
    Console.WriteLine($"id: {id}; name: {name}");
}

It looks like you can also deconstruct the ValueTuple inline:

if (val is ValueTuple<int, int>(var id, var name))
{
    Console.WriteLine($"id: {id}; name: {name}");
}

... which is somewhat horrific, but appears to be legal.

I might have expected val is (int, int) pair) to work, but it seems nobody's designed this case (yet).

Bakker answered 12/5, 2019 at 20:39 Comment(4)
The first code block gives the same error. The second one works but I don't want to use Item1, Item2 etc.Reorganization
@Reorganization It works in sharplab - might be new in C# 8. sharplab.io/…Bakker
@Reorganization found another way, added to my answerBakker
I think my editor does not let me to use c#8 yet (I think because it is preview). Your updated answer is probably the closest I can get for now.Reorganization

© 2022 - 2024 — McMap. All rights reserved.