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 ValueTuple
s be assigned covariantly, but MyValueTuple
s can't?
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.
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.
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.
Tuple types are value types; tuple elements are public fields. That makes tuples mutable value types. The tuples feature requires the System.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With