C# C“结构”;这个=……”是什么意思;

C# C“结构”;这个=……”是什么意思;,c#,struct,C#,Struct,我刚刚在reflector中浏览了一个文件,在struct构造函数中看到了这一点: this = new Binder.SyntaxNodeOrToken(); 我以前没见过这个术语。有人能解释一下这个作业在C#中的意思吗。谷歌很难做到 它基本上替换了值。它有效地将所有字段从右侧复制到左侧。。。除非即使字段是只读的,它也可以工作。是的,它确实看起来很奇怪,而且有点吓人 例如: using System; class Test { static void Main() {

我刚刚在reflector中浏览了一个文件,在struct构造函数中看到了这一点:

this = new Binder.SyntaxNodeOrToken();

我以前没见过这个术语。有人能解释一下这个作业在C#中的意思吗。谷歌很难做到

它基本上替换了值。它有效地将所有字段从右侧复制到左侧。。。除非即使字段是只读的,它也可以工作。是的,它确实看起来很奇怪,而且有点吓人

例如:

using System;

class Test
{
    static void Main()
    {
        Point point = new Point(10, 20);
        point.ReplaceWith(new Point(2, 3));
        Console.WriteLine(point); // (2, 3)
    }
}

struct Point
{
    private readonly int x;
    private readonly int y;

    public Point(int x, int y)
    {
        this.x = x;
        this.y = y;
    }

    public void ReplaceWith(Point other)
    {
        this = other;
    }

    public override string ToString()
    {
        return string.Format("({0}, {1})", x, y);
    }
}
有关更多信息,请参阅C#4规范第7.6.7节,其中包括:

  • [关于在结构构造函数中使用的文本]

  • 用于结构的实例方法或实例访问器中的主表达式时,它被分类为变量。变量的类型是发生使用的结构的实例类型

    • 如果方法或访问器不是迭代器,
      this
      变量表示调用方法或访问器的结构,其行为与结构类型的
      ref
      参数完全相同

    • [关于迭代器的文本]


如果
s1
s2
Foo
类型的结构,带有
f1
f2
f3
,则语句
s1=s2
在语义上等同于

s1.f1 = s2.f1;
s1.f2 = s2.f2;
s1.f3 = s2.f3;
Foo temp;
call Foo's constructor (out temp, whatever);
this.f1 = temp.f1;
this.f2 = temp.f2;
this.f3 = temp.f3;
除了不应假设赋值操作的顺序(甚至读写的相对顺序;例如,生成的代码可能将所有三个字段读入寄存器,然后将所有三个字段写入)。所有字段都将被复制,不管它们是公共的还是私有的、可变的还是所谓的不可变的。不会调用属性getter或setter;源结构和目标结构都不会收到结构的字段被复制或覆盖的通知

语句
this=newfoo(无论什么)在C#(*)中等于

s1.f1 = s2.f1;
s1.f2 = s2.f2;
s1.f3 = s2.f3;
Foo temp;
call Foo's constructor (out temp, whatever);
this.f1 = temp.f1;
this.f2 = temp.f2;
this.f3 = temp.f3;
(*)vb.net中的结构构造函数语义不同

如上所述,字段赋值不考虑字段是公共的还是私有的,也不考虑它们是否假定是不变的

我认为(与其他人的观点相反)结构应该经常公开可变字段的一个原因是语法如下:

// Assume myKVP is a field of type KeyValuePair<Wizzle, int>
rr = new KeyValuePair<Wizzle, int>(myKVP.Key, myKVP.Value + 1);
换句话说,该语句不会使
myKVP
报告到不同的实例;相反,它创建一个新实例,通过用新实例的字段覆盖旧实例的字段来改变旧实例,然后丢弃新实例。如果在执行上述分配时,某些代码正在评估
myKVP.ToString()
,则突变将影响正在打印的
myMVP
实例


结构可以有有用的语义,但所谓的“不可变”结构却没有。非平凡结构(可以为其创建不同于默认值的值的结构)是可变的,当且仅当它们保存在可变存储位置时,才是可变的,而不考虑类型强加的任何语义。自变异结构,即在除构造函数和属性设置器之外的任何方法中变异
this
的结构,可能会有一些意外行为,因为编译器无法禁止在不可变结构实例上调用将变异
this
的其他方法。但是,结构字段的公开暴露不会造成任何此类危险。由于非平凡结构的可变实例的所有字段本质上都是可变的,无论该结构可能做出任何允许变异的尝试,并且结构的不可变实例的所有字段都是不可变的,即使它们是公开的,一个试图使其字段“不可变”的结构实际上是在说谎。有时可能有用的谎言(例如,如果字段内容应该服从某些不变量),但如果没有真正的原因就不应该说出来。

除非我疯了,否则这是一个错误。@ChaosPandion:要么我们都疯了,要么我同意。也许reflector搞错了?@ChaosPandion这对C#@JaredPar中的
struct
是完全合法的-现在我想我知道了关于C#的一切。。。当然我知道我疯了。@ChaosPandion:看我的答案,举个例子。这太奇怪了。。。C#压倒了我(也许还有很多其他人)的编程能力concept@ziq:不要忘记,
是值类型中的“全部值”,而不是引用。我认为这是关键的部分。如何才能完成?在成员函数运行时替换自己(在本例中ReplaceWith@luiscubal:或者,如“
结构中的只读
字段在道德上等同于结构作者在没有资金支持的情况下写支票。”@DanielPryden我不明白你的论点。你的
myKVP
语法示例令人困惑,而且似乎不符合C#语法。如果一个结构是不可变的,那么为什么它会包含“其他将变异
的方法?”?在你的最后一段中,关于值类型和该类型的实例之间的区别似乎有一些混淆。你能编辑你的答案以更好地解释你想说什么吗?@DanielPryden:我只是补充了几条评论,并试图澄清后一段。最初的问题是为什么可以重播用另一个结构替换
this
。可以这样做的原因是,一个不是真的替换
this
;一个只是用另一个结构替换其所有字段的内容。然后我想说,一个可以变异“this”的事实,无论是覆盖整个内容还是更改其字段,都不意味着应该这样做。