これはC#7.3(フレームワーク4.8)で正しくコンパイルされます。
(string, string) s = ("a", "b");
(object, string) o = s;
これは次の構文シュガーであることを知っています。これも正しくコンパイルされます。
ValueTuple<string, string> s = new ValueTuple<string, string>("a", "b");
ValueTuple<object, string> o = s;
したがって、ValueTuplesを割り当てることができるようです 共変 、これは素晴らしいです!
残念ながら、なぜなのかわかりません:C# インターフェイスとデリゲートでのみサポートされている共分散 という印象を受けました。 ValueType
はどちらでもありません。
実際、自分のコードでこの機能を複製しようとすると失敗します。
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>'
それでは、なぜValueTuple
sを共変的に割り当てることができますが、MyValueTuple
sは割り当てられないのですか?
ここで実際に起こっていることは、破壊的な任務だと思います。タプル割り当ては、そのコンポーネントを暗黙的に変換しようとします。string
をobject
に割り当てることが可能であるため、ここでそれが行われます。
この言語は、同じ数の要素を持つタプル型間の割り当てをサポートしています。各右側要素は、対応する左側要素に暗黙的に変換できます。他の変換は割り当てでは考慮されません。