Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What makes ValueTuple covariant?

This compiles correctly in C# 7.3 (Framework 4.8):

(string, string) s = ("a", "b"); (object, string) o = s; 

I know that this is syntactic sugar for the following, which also compiles correctly:

ValueTuple<string, string> s = new ValueTuple<string, string>("a", "b"); ValueTuple<object, string> o = s; 

So, it appears that ValueTuples can be assigned covariantly, which is awesome!

Unfortunately, I don't understand why: I was under the impression that C# only supported covariance on interfaces and delegates. ValueType is neither.

In fact, when I try to duplicate this feature with my own code, I fail:

struct MyValueTuple<A, B> {     public A Item1;     public B Item2;      public MyValueTuple(A item1, B item2)     {         Item1 = item1;         Item2 = item2;     } }  ...  MyValueTuple<string, string> s = new MyValueTuple<string, string>("a", "b"); MyValueTuple<object, string> o = s; // ^ Cannot implicitly convert type 'MyValueTuple<string, string>' to 'MyValueTuple<object, string>' 

So, why can ValueTuples be assigned covariantly, but MyValueTuples can't?

like image 317
Heinzi Avatar asked Dec 19 '19 14:12

Heinzi


People also ask

How to create ValueTuple?

You can create a pair value tuple by using ValueTuple <T1, T2>(T1, T2) constructor. It initializes a new instance of the ValueTuple <T1, T2> struct. But when you create a value tuple using this constructor, then you have to specify the type of the element stored in the value tuple.

What is ValueTuple?

ValueTuple is a structure introduced in C# 7.0 which represents the value type Tuple. It is already included in . NET Framework 4.7 or higher version. It allows you to store a data set which contains multiple values that may or may not be related to each other.

How to initialize value tuple in c#?

ValueTuple Initialization It can be created and initialized using parentheses () and specifying the values in it. var person = (1, "Bill", "Gates"); //equivalent Tuple //var person = Tuple. Create(1, "Bill", "Gates"); The ValueTuple can also be initialized by specifying the type of each element, as shown below.

Is tuple a value type C#?

Tuple types are value types; tuple elements are public fields. That makes tuples mutable value types. The tuples feature requires the System.


1 Answers

I believe what is actually happening here is a destructuring assignment. Tuple assignment will try to implicitly convert its components, and as it is possible to assign string to object, that is what happens here.

The language supports assignment between tuple types that have the same number of elements, where each right-hand side element can be implicitly converted to its corresponding left-hand side element. Other conversions aren't considered for assignments.

Source

See it on sharplab.io

like image 62
Gareth Latty Avatar answered Sep 20 '22 22:09

Gareth Latty