【问题标题】:C# field vs. property [duplicate]C# 字段与属性 [重复]
【发布时间】:2012-02-05 02:07:11
【问题描述】:

可能重复:
Difference between Property and Field in C#

我认为基本属性 ({ get; set; }) 与公共字段相同,只有能够在不破坏二进制兼容性的情况下更改它们的优点。按照我在这里得到的答案https://stackoverflow.com/a/8735303/331785,我发现属性也有一个缺点。如果它们是值类型,则不能通过引用访问它们。为什么会这样,还有什么其他区别?

【问题讨论】:

  • 这是一个谬论。属性不能通过引用访问,句号。您犯了将引用传递与引用类型混淆的常见错误。
  • 也就是说一个引用类型的引用默认是传值的。对于引用类型和值类型,始终使用 refout 关键字进行引用传递。
  • @DipuRaj 我觉得这个问题并不完全重复,因为它询问为什么会发生上述行为,而该问题没有。

标签: c# properties


【解决方案1】:

我发现属性也有一个缺点。如果它们是值类型,则不能通过引用访问它们。这是为什么呢

因为在幕后,属性只是一种方法。如果您查看 IL,您会看到像 get_PropertyNameset_PropertyName 这样的方法。这样做的问题是为了支持使用引用,您需要能够返回方法的引用。

public ref T MyProperty
{
    get
    {
         return ref _underlyingField;
    }
}

更新:从 C# 7.0 开始,可以使用上述语法。

上一个答案的剩余部分:

这当然是something entirely possible in the CLR;但没有被 C# 语言公开。

尽管有可能,但 CLR 需要进行一些调整以使其保持可验证性。该属性的语法必须支持它。

但是,这些有用吗?正如你所说,一个领域可以做到这一点。如果你需要它;使用一个字段。支持它需要很多工作。可能在极少数情况下是合适的;并且会产生很多情况,一开始只使用一个字段可能会更好。

【讨论】:

    【解决方案2】:

    属性只是getX()setX() 方法的糖衣语法。它看起来和行为都像一个字段,但它实际上只是两种方法。添加自动属性的原因是为了避免重复创建字段并为属性创建标准的 getter 和 setter,并且更简单地允许在不更改接口的情况下更改实现。

    如果它们是值类型,则不能通过引用访问它们的原因是因为值类型通常在堆栈上,并且因为您只是在调用一个方法。必须调用属性中的 getter,并且必须将返回的值压入堆栈才能被引用。

    【讨论】:

    • -1 用于传播值类型在堆栈上的神话(即使是“一般”)。如果属性(或字段)属于一个类,它不会在堆栈上。
    • @JonSkeet 我认为他在谈论 getter 的返回值,它首先会出现在寄存器中,然后可能会出现在堆栈中,因此它可以获得一个可以引用的地址。
    猜你喜欢
    • 2013-03-11
    • 2011-06-19
    • 1970-01-01
    • 1970-01-01
    • 2010-12-05
    • 2013-10-15
    • 2011-11-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多