【发布时间】:2016-11-27 11:47:34
【问题描述】:
假设你有这样的课程
public class Foo
{
public int Bar { get; set; } = 42;
}
如果您尝试将属性作为ref 参数传递,编译器会发出错误
CS0206 属性或索引器不能作为 out 或 ref 传递 参数
这是可以理解的,因为实际上上面示例中的属性被编译成get_Bar() 和set_Bar() 方法。但是,如果您在属性上使用增量运算符,例如
var foo = new Foo();
foo.Bar++;
它按预期工作。为此,编译器需要生成类似这样的伪代码:
var foo = new Foo();
int tmp = foo.get_Bar();
tmp++;
foo.set_Bar(tmp);
所以理论上编译器可以为ref 做类似的事情:
var foo = new Foo();
int tmp = foo.get_Bar();
DoSomething(ref tmp);
foo.set_Bar(tmp);
编译器不这样做是否有技术原因,或者这只是 C# 团队的设计决定?
【问题讨论】:
-
这实际上是 VB.NET 编译器为使此类代码编译所做的工作。它是一种旨在友好的语言,C# 旨在纯粹。如果纯度与隐藏可能很昂贵的 setter 调用不太兼容,则会在错误的位置生成异常,可能会生成难以诊断的编译错误或导致别名问题。然而,++ 运算符不是很纯粹,并且以不止一种方式绕过规则。例如,您可以在不进行强制转换的情况下增加 byte。他们决定让它实用。选择。
-
@HansPassant 如果您可以将您的评论详细说明为答案,我会接受它
-
@Abion47 我不认为这是重复的,因为您链接的问题没有解决增量/减量运算符。
-
我无法详细说明,我从未被邀请参加 C# 团队设计会议。所以用户需要事实而不是猜测,他们也应该这样做。 Eric Lippert 可能会出现,尽管在做出决定时他也不在身边。您的问题无法回答,得到回答也不是那么重要,因此不会造成重大损失。
标签: c# properties ref