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