这可以在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#只支持interface和委托的协方差。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
不能呢?
实际上,对于第二个任务,反编译后的代码如下所示:
—
Lasse V. Karlsen,
ValueTuple<object, string> o = new ValueTuple<object, string>(s.Item1, s.Item2);
元组很奇怪,并且完全在c#编译器前端中实现,而不是依赖于底层的CLR表示。那个赋值运算符没有按照您的想法做。
—
杰里米·莱克曼
添加一个隐式运算符
—
Çöđěxěŕ
public static implicit operator MyValueTuple<A, B>(MyValueTuple<string, string> v) { throw new NotImplementedException(); }
以解构分配。另外,顺便问个好问题!
@Çöđěxěŕ靶心!使其可编译,并且按预期方式引发异常
—
Mong Zhu
null
给Nullable<T>
它一样。