gpt4 book ai didi

c# - 无法将可解构类型隐式转换为元组

转载 作者:行者123 更新时间:2023-12-01 21:37:39 28 4
gpt4 key购买 nike

我有两个使用 Deconstruct() 方法的结构(Point 和 Size)。两者都返回 (int, int) 元组。

我试图在 switch 中将它们解构为 (int, int) 元组变量,但没有成功。编译器给我错误:

Cannot implicitly convert type 'Size' to '(int, int)'.

如何将这两个结构解构为一个元组,以便能够在第二个 switch 表达式中使用它?

using System;

class Program
{
static string DescribeSize<TDeconstructable>(TDeconstructable deconstructableStruct)
where TDeconstructable : struct
{
(int, int) xy;
switch (deconstructableStruct)
{
case Size size:
xy = size; //CS0029 error: Cannot implicitly convert type 'Size' to '(int, int)'
break;
case Point point:
xy = point; //CS0029 error: Cannot implicitly convert type 'Point' to '(int, int)'
break;
default:
xy = (0, 0);
break;
}

return xy switch
{
(0, 0) => "Empty",
(0, _) => "Extremely narrow",
(_, 0) => "Extremely wide",
_ => "Normal"
};
}

static void Main(string[] args)
{
var size = new Size(4, 0);
var point = new Point(0, 7);
Console.WriteLine(DescribeSize(size));
Console.WriteLine(DescribeSize(point));
}
}

public struct Point
{
public int X { get; set; }
public int Y { get; set; }

public Point(int x, int y)
{
X = x;
Y = y;
}

public void Deconstruct(out int x, out int y)
{
x = X;
y = Y;
}
}

public readonly struct Size
{
public int W { get; }
public int H { get; }

public Size(int w, int h)
{
W = w;
H = h;
}

public void Deconstruct(out int w, out int h)
{
w = W;
h = H;
}
}

最佳答案

没有到 ValueTuple 的隐式转换,并且您的赋值不会调用解构。您实质上是在尝试执行以下不合法的操作:

xy = (ValueTuple<int, int>)size;

您需要两个变量,而不是一个。如果您认为解构只是调用 Deconstruct 方法的编译器技巧/语法糖,这一点就会变得更加明显。如果您打算手动调用它,则需要将两个变量作为out参数传递,而不是一个。

int x, y;
size.Deconstruct(out x, out y);

没有采用单个 元组的重载。那将如何工作?只有一个变量。我想您可能认为编译器可以做一些类似于:

size.Deconstruct(out xy.Item1, out xy.Item2);

不幸的是,它没有。对于您的情况,您需要单独声明变量(而不是作为 ValueTuple),然后使用解构和元组语法来分配给它们。如果您愿意,可以将 default 情况下的赋值从 switch 中移出,让两个变量的声明更像元组:

var (x, y) = (0, 0); // two variables 
switch (deconstructableStruct)
{
case Size size:
(x, y) = size;
break;
case Point point:
(x, y) = point;
break;
}

以后你仍然可以打开值,你只需要使用元组语法:

return (x, y) switch {
(0, 0) => "Empty",
(0, _) => "Extremely narrow",
(_, 0) => "Extremely wide",
_ => "Normal"
};

参见 this answer一个好的替代方案:如果您真的需要一个本身是元组类型的变量(并且您可以也不需要),则编写您自己的隐式转换运算符不介意修改 SizePoint 类型来添加此行为)。

关于c# - 无法将可解构类型隐式转换为元组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61762167/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com