更改值types的“this”variables
显然你可以在你的结构中的任何地方(但不是在类中)更改this
值:
struct Point { public Point(int x, int y) { this = new Point(); X = x; Y = y; } int X; int Y; }
我从来没有见过这个,也没有需要它。 为什么要这样做呢? 埃里克·利珀特提醒我们 ,一个特点必须是合理的实施。 多大的用例可以certificate这一点? 有没有任何情况下,这是非常宝贵的? 我找不到任何文件 1 。
另外,对于调用构造函数,已经有了一个更好的已知替代语法,所以这个特性有时是多余的:
public Point(int x, int y) : this() { X = x; Y = y; }
我通过C#第4版在Jeffrey Richter的CLR中find了这个特性。
1)显然它是在C#规范 。
好问题!
根据定义,值types按值复制。 如果this
实际上不是存储位置的别名,那么构造函数将初始化一个副本,而不是初始化您打算初始化的variables。 这将使构造函数相当有用! 同样的方法; 是的,可变的结构是邪恶的,但如果你打算再做一个可变的结构, this
必须是被变异的variables,而不是它的值的副本。
您所描述的行为是该devise决策的逻辑结果:因为this
variables是别名,您可以分配给它,就像您可以分配给任何其他variables一样。
直接分配给它,而不是分配给它的字段, this
有点奇怪。 直接分配给this
,然后覆盖那个任务的100%是更奇怪的!
另外一种避免将this
作为接收者存储别名的替代devise是将this
从短期存储池中分配出来,在ctor中进行初始化,然后按值返回。 这种方法的缺点是,它使复制elision优化几乎是不可能的,它使得ctors和方法奇怪地不一致。
另外,我找不到任何文档。
你有没有尝试在C#规范? 因为我可以find它的文档(7.6.7):
当
this
在一个结构的实例构造函数中的主expression式中使用时,它被分类为一个variables。 variables的types是用法发生的结构体的实例types(第10.3.1节),variables表示正在构造的结构体。 结构的实例构造函数的this
variables的行为与结构types的out
参数完全相同 – 特别是,这意味着variables必须在实例构造函数的每个执行path中明确分配。当
this
在一个结构的实例方法或实例访问器中的主expression式中使用时,它被分类为一个variables。 variables的types是用法发生的结构的实例types(第10.3.1节)。
- 如果方法或访问器不是迭代器(第10.14节),则
this
variables表示方法或访问器被调用的结构,其行为与结构types的ref
参数完全相同。- 如果方法或访问器是一个迭代器,则
this
variables表示方法或访问器被调用的结构的副本,其行为与结构types的值参数完全相同。
至于它的一个用例,我不能马上想到很多 – 关于我得到的唯一的东西是如果你想在构造函数中分配的值是昂贵的计算,并且你有一个caching值想要复制到this
,可能会很方便。
值types的存储位置,包含该types的公共和专用字段的存储位置的聚合。 将值types传递给普通(值)参数将在物理上和语义上传递其所有字段的内容。 传递一个值types作为ref
参数是在语义上传递所有字段的内容,尽pipe使用一个“byref”来传递所有的字段。
在结构上调用一个方法相当于将结构(以及它的所有字段)作为ref
parameter passing,除了一个折痕:通常,C#和vb.net都不允许将只读值作为parameter passing参数。 但是,两者都允许在只读值或临时值上调用结构方法。 他们通过复制所有结构(以及所有的字段),然后将该副本作为ref
parameter passing来完成此操作。
由于这种行为,有些人称可变结构为“邪恶”,但唯一不幸的是,C#或vb.net都没有定义任何属性来指示结构成员或属性是否可以在不能直接通过ref
。