C# field vs. property
0
我认为基本属性({ get; set; })与公共字段相同,只具有在不破坏二进制兼容性的情况下更改它们的优势。根据我在这里得到的答案https://stackoverflow.com/a/8735303/331785,我发现属性也有缺点。如果它们是值类型,则不能通过引用访问它们。为什么会这样,还有其他什么区别?
- 这里有答案:stackoverflow.com/questions/653536/…
- 这是个谬论。无法通过引用访问属性,完全停止。您犯了一个常见的错误:将引用传递与引用类型混淆。
- 也就是说,默认情况下,引用类型的引用是按值传递的。对于引用和值类型,始终使用ref或out关键字进行引用传递。
- @我觉得这个问题并不是一个完全重复的问题,因为它是在问为什么上述行为会发生,而这个问题并不是。
0
因为在封面下,属性只是一个方法。如果你看一下IL,你会看到像get_PropertyName和set_PropertyName这样的方法。问题是为了支持使用引用,您需要能够返回方法的引用。
1 2 3 4 5 6 7
| public ref T MyProperty
{
get
{
return ref _underlyingField;
}
} |
更新:从C 7.0开始,可以使用上面描述的语法。
上一个答案的剩余部分:
当然,这在clr中是完全可能的,但不会被C语言暴露。
虽然有可能,但是clr需要进行一些调整,以使其保持可验证性。属性的语法必须支持它。
但是,这些有用吗?正如您所说,字段可以做到这一点。如果你需要的话,用一块地。支持它需要很多工作。在适当的情况下,可能会有一些情况;并且会创建许多情况,在这些情况下,仅仅使用一个字段一开始可能会更好。
属性只是getX()和setX()方法的糖衣语法。它看起来像一个字段,但实际上它只是两种方法。添加auto属性的原因是为了避免重复创建字段和为属性创建标准的getter和setter,并使在不更改接口的情况下更改实现更加简单。
如果它们是值类型,则不能通过引用访问它们的原因是,值类型通常位于堆栈中,并且您只是调用了一个方法。必须调用属性中的getter,并且必须在堆栈上推送返回的值,然后才能引用它。
- -1用于传播堆栈上的值类型神话(即使"一般")。如果属性(或字段)是类的,它将不在堆栈上。
- @Jonskeet我认为他在谈论getter的返回值,它首先会出现在寄存器中,然后可能出现在堆栈中,这样它就得到了一个可以被引用的地址。