Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using `is` operator with value type tuples gives error

Tags:

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.

like image 258
ilkerkaran Avatar asked May 12 '19 20:05

ilkerkaran


People also ask

Is tuple value type?

Tuple types are value types; tuple elements are public fields. That makes tuples mutable value types.

Can tuple be null C#?

Comparing null to null The null == null comparison is allowed, and the null literals do not get any type. In tuple equality, this means, (0, null) == (0, null) is also allowed and the null and tuple literals don't get a type either.

How do you declare a tuple in C#?

The Tuple<T> class was introduced in . NET Framework 4.0. A tuple is a data structure that contains a sequence of elements of different data types. It can be used where you want to have a data structure to hold an object with properties, but you don't want to create a separate type for it.

What is the use of tuple in C#?

Tuples are generally used when you want to create a data structure which contains objects with their properties and you don't want to create a separate type for that. Features of Tuples: It allows us to represent multiple data into a single data set. It allows us to create, manipulate, and access data set.

How do you use == and == operators in a tuple?

Beginning with C# 7.3, tuple types support the == and != operators. These operators compare members of the left-hand operand with the corresponding members of the right-hand operand following the order of tuple elements. As the preceding example shows, the == and != operations don't take into account tuple field names.

What is the difference between a tuple and a value tuple?

The main differences are as follows: 1 ValueTuple types are value types. Tuple types are reference types. 2 ValueTuple types are mutable. Tuple types are immutable. 3 Data members of ValueTuple types are fields. Data members of Tuple types are properties.

Are there any invalid values stored in a tuple?

Furthermore, there are no invalid values for the items stored within a tuple. Any validation would be enforced in the data type of the item itself, not in the assignment of one of the Item properties on the tuple. For this reason, properties on the tuple don’t provide any value, and there’s no conceivable future value they could provide.

How do I solve an error when assigning a tuple?

To solve the error, figure out how the variable got assigned a tuple and correct the assignment, or access a specific value in the tuple. Here is an example of how the error occurs.


Video Answer


1 Answers

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

like image 148
canton7 Avatar answered Oct 13 '22 23:10

canton7