Value元组初始化是违反直觉的

问题描述 投票:2回答:1

[星期天晚上我一直在观看一些会议,这次我亲身体验了这一会议Conference Link

我发现非常有趣的地方认为有一个简单的代码示例:

struct Point
{
    private double x;

    public double X { get => x; set => x = value; }

    private double y;

    public double Y { get => y; set => y = value; }

    public Point(double x, double y) => (this.x, this.y) = (x, y);

    public void SwapCode() => (X, Y) = (Y, X);

}

在Main

var point = new Point(10.0, 11.0);

Console.WriteLine($"x: {point.X}, y: {point.Y}");
point.SwapCode();
Console.WriteLine($"x: {point.X}, y: {point.Y}");

并且有此输出:

x: 10, y: 11
x: 11, y: 10

所以有一些问题:

如何运作?

  1. 我的意思是,元组应该转换为Tuple<T, K>,应使用值的副本进行初始化,但是至少在我看来,它为变量分配了值,这有点违反直觉。

  2. 而且我想知道这是否只是糖语语法,还是在这种情况下发生了一些不可思议的魔术,但是我无法发现它吗?

c# .net tuples
1个回答
2
投票
首先是

结构应为不可变。即使您可以执行此操作,也可能不应该这样做。

第二,您的SwapCode实际上正在执行此操作,as seen here

public void SwapCode() { double num = Y; double num2 = X; double num4 = X = num; num4 = (Y = num2); }

是的,有点奇怪。但是,它只是C#7中引入的一点语法魔术。它实际上是在使用deconstruct方法(术语

。Net

使用)为要提取的每个参数提供一组out arguments。在这种情况下,它是您提供的属性/字段!要更清楚一点,请考虑这两个功能等效的代码块

(int x, int y) asd = (1, 2); // create a Value Tuple (int x, int y) = asd; // deconstruct it (x, y) = (x, y); // assign to the deconstructed type // All the above now has the swapped values // they are all pointing to the same variables/memory // You could even take this further by x = 10; y = 11; // Once again, x and y, asd, and (x, y) all have the same values // Because they are the same // ---------------------------------------------------- int x = 1; int y = 2; (x, y) = (y, x); // we are just deconstructing our original variables // All the above now has the swapped values // they are all pointing to the same variables/memory

[[[[[Note

]:如您所见,这也是交换2个变量的一种更成功的方法,因为您不必使用临时变量,友好的CLR会为您做到这一点] 无论如何,无论如何您都不应该使用struct来执行此操作,因为各种原因,它们实际上应该是不可变的
© www.soinside.com 2019 - 2024. All rights reserved.