これは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
ことができるのに、それができないのはなぜですか?
実際には第二の割り当てについては、このような、逆コンパイルコードのルックス:
—
ラッセV. Karlsenの
ValueTuple<object, string> o = new ValueTuple<object, string>(s.Item1, s.Item2);
タプルは奇妙で、基礎となるCLR表現に依存するのではなく、c#コンパイラのフロントエンドに完全に実装されています。その代入演算子はあなたが思っていることをしていません。
—
ジェレミーレイクマン
暗黙の演算子を追加して
—
Çöđěxěŕ
public static implicit operator MyValueTuple<A, B>(MyValueTuple<string, string> v) { throw new NotImplementedException(); }
、割り当てを分解します。ちなみに、いい質問ですね!
@Çöđěxěŕブルズアイ!これによりコンパイル可能になり、例外が期待どおりにスローされます
—
Mong Zhu
null
にNullable<T>
それは構造体だにもかかわらず。