更改值类型的'this'变量

Dan*_*ker 64 c# this value-type

显然,您可以this从结构中的任何位置更改值(但不能在类中):

struct Point
{
    public Point(int x, int y)
    {
        this = new Point();
        X = x; Y = y;
    }
    int X; int Y;
}
Run Code Online (Sandbox Code Playgroud)

我以前也没见过这种情况,也从未见过它.为什么一个人想要这样做?Eric Lippert提醒我们,必须证明某个功能是合理的.有什么好的用例可以证明这一点?有什么场景这是非常宝贵的吗?我找不到任何文件1.

此外,对于调用构造函数,已经有一个更好的已知替代语法,因此此功能有时是多余的:

public Point(int x, int y)
    : this()
{
    X = x; Y = y;
}
Run Code Online (Sandbox Code Playgroud)

通过C#第4版在Jeffrey Richter的CLR中找到了这个功能.
1)显然它符合C#规范.

Eri*_*ert 54

好问题!

根据定义,值类型按值复制.如果this实际上不是存储位置的别名,那么构造函数将初始化副本而不是初始化您要初始化的变量.这会使构造函数变得不那么有用!同样的方法; 是的,可变结构是邪恶的,但如果你要再次制作一个可变结构,this必须是变异的变量,而不是它的值的副本.

您描述的行为是该设计决策的逻辑结果:由于this别名变量,您可以分配给它,就像您可以分配给任何其他变量一样.

直接分配给this那样的,而不是分配给它的字段有点奇怪.直接分配this然后覆盖100%的任务甚至更奇怪!

避免this为接收器的存储设置别名的另一种设计是分配this短期存储池,在ctor中初始化它,然后按值返回它.这种方法的缺点是它使复制省略优化几乎不可能,并且它使得ctors和方法奇怪地不一致.

  • @Virtlink:假设语言设计团队采纳了您的提案.如果有人在ctor中调用"M(out this)",你会提出什么?在这种情况下,`this`应该被视为*而不是变量*吗? (4认同)
  • @Virtlink:您将值类型作为out*传递,因为您希望它们由被调用者*初始化.假设一个ctor编写器已经有一个方法可以正确初始化该类型的变量; 为什么他们不会使用它? (2认同)

Dam*_*ver 10

另外,我找不到任何文件.

您是否尝试过查看C#规范?因为我可以找到它的文档(7.6.7):

  • this在结构的实例构造函数中的primary-expression中使用时,它被归类为变量.变量的类型是发生用法的结构的实例类型(第10.3.1节),变量表示正在构造的结构.this结构的实例构造函数的变量out与结构类型的参数完全相同- 特别是,这意味着必须在实例构造函数的每个执行路径中明确赋值变量.

  • 当在结构的实例方法或实例访问器this中的primary-expression中使用时,它被归类为变量.变量的类型是发生使用的结构的实例类型(第10.1.3节).

    • 如果方法或访问器不是迭代器(第10.14节),则该this变量表示调用方法或访问器的结构,其行为ref与结构类型的参数完全相同.
    • 如果方法或访问器是迭代器,则该this变量表示为其调用方法或访问器的结构的副本,并且其行为与结构类型的参数完全相同.

至于它的一个用例,我不能立即想到很多 - 关于我唯一能得到的是你想在构造函数中分配的值计算成本高,而且你有一个缓存值想要复制this,可能很方便.