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?
null
to aNullable<T>
even though it's a struct. – NicksValueTuple<object, string> o = new ValueTuple<object, string>(s.Item1, s.Item2);
– Pharmacypublic static implicit operator MyValueTuple<A, B>(MyValueTuple<string, string> v) { throw new NotImplementedException(); }
its deconstructing the assignment. Also, great question by the way! – Unavoidable