Fiddle here。
给定一个函数(string a, string b) F()
,您可以解构它返回的元组:
var (a, b) = F();
(string c, string d) = F();
或者您可以分配它:
var (a, b) e = F();
(string a, string b) f = F();
var g = F(); // One of these things is not like the others.
类解构函数的行为类似于第一种情况。给定一个带有
C
的Deconstructor(out string a, out string b)
类:var c = new C();
var (h, i) = c;
(string j, string k) = c;
但是编译器不会使用解构函数将其隐式转换为元组:
// Cannot implicitly convert type 'C' to '(string a, string b)'
var (a, b) l = c;
显然,您可以基于解构函数机械地编写隐式转换:
public static implicit operator (string a, string b) (C c)
{
c.Deconstruct(out string a, out string b);
return (a, b);
}
尽管在解构情况和赋值情况之间的语法上存在视觉相似性,但将引用分配给元组与将类分解为变量然后将其放入新的元组并不相同。但是,您可以将
(int x, int y)
隐式转换为(double x, double y)
。值元组是一种语法糖功能,它在功能上看起来像它在做的事情一样,无需理会实现细节。如果我想到了这一点,C#团队就会想到这一点,并且如果他们选择不对隐式转换添加“魔术”支持,那么他们就有充分的理由1。
是否有积极的理由为什么自动进行隐式转换会是个坏主意?
抑或是仅仅是被认为不足以证明成本合理的那些功能之一?
这是that fiddle的代码:
public class Program
{
public static void Main()
{
(string a, string b) = F();
(string a, string b) ab = F();
Console.WriteLine($"a: {a} b: {b} ab: {ab}");
var c = new C();
(string d, string e) = c;
// Cannot implicitly convert type 'C' to '(string a, string b)'
(string a, string b) f = c;
Console.WriteLine($"d: {d} e: {e} f: {f}");
// Covariance
(object c, object d) g = F();
// Implicit conversion
(double x, double y) t = G();
}
public static (string a, string b) F()
=> ("A", "B");
public static (int x, int y) G()
=> (0, 1);
}
public class C
{
public String A = "A";
public String B = "B";
public void Deconstruct(out String a, out String b)
{
a = A;
b = B;
}
}
1 C#团队可能并不比每个人都聪明,但是我从来没有亏过他们至少像我一样聪明的钱。
最佳答案
具有解构功能的能力就像隐式转换器一样,这是在发布C#7之前要求的(对我来说,这里对我有偏见)。团队的反馈是(正如我所阅读的那样),因为它被要求离C#7版本太近,并且实现时间太长,因此没有考虑。由于这将是一个重大变化,所以这将永远不会发生。
有关此问题的实际讨论,请参见“Allow Deconstruct and implicit operator to both support deconstruction and conversion to tuple types” roslyn repo问题。
关于C#7值元组/解构不对称,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43920598/