私有字段和私有属性的区别

Posted

技术标签:

【中文标题】私有字段和私有属性的区别【英文标题】:Differences between Private Fields and Private Properties 【发布时间】:2010-09-29 11:45:53 【问题描述】:

使用私有属性而不是私有字段有什么区别

private String MyValue  get; set; 

// instead of

private String _myValue;

public void DoSomething()

   MyValue = "Test";

   // Instead of

   _myValue = "Test";

有任何性能问题吗?还是只是一个命名约定?

【问题讨论】:

【参考方案1】:

私有属性允许您抽象内部数据,以便对内部表示的更改不需要影响您的实现的其他部分,即使在同一个类中也是如此。私有字段不提供此优势。使用 C# 3.0 中的自动属性,我很少看到需要直接实现字段——私有或公共。

【讨论】:

但是,如果您决定它需要除无逻辑的单行 getter 和 setter 之外的其他东西,将字段重构为属性不需要任何成本。【参考方案2】:

您可以从属性(私有、公共...)中获得的最大好处是它可以产生计算值与设定值。例如

class Person  
  private DateTime _birthday;
  private int _age  get  return (DateTime.Now - _birthday).TotalYears; 

这种模式的优点是只需为 N 个其他值更新一个值以反映更改。无论可访问性如何,属性都是如此。私有财产与非私有财产相比没有特别的优势(当然除了私有)

【讨论】:

【参考方案3】:

您很少希望将属性设为私有。提供私有财产的规定只是为了完整性。而且,如果您的属性只是获取/设置字段的值,则不会有性能差异,因为它很可能会被 JIT 编译器内联。

【讨论】:

没有给出这个答案的理由。其他答案解释了为什么私有属性比私有字段更可取。【参考方案4】:

除此之外已经回答的问题,性能、语义和完整性,我见过一个有效的私有属性而不是私有字段的案例:

public class Item

    private Item _parent;
    private List<Item> _children;

    public void Add(Item child)
    
        if (child._parent != null)
        
            throw new Exception("Child already has a parent");
        
        _children.Add(child);
        child._parent=this;
    

假设我们不想出于任何原因公开 Parent,但我们可能还想进行验证检查。是否应该能够将父母作为孩子添加到其孩子之一?

要解决此问题,您可以将其设为属性并检查循环引用。

【讨论】:

【参考方案5】:

属性访问将(部分)变慢,因为它会调用 getter/setter。好处是您可以进行数据验证,例如,如果您更改要保护的属性,则可以过滤到继承者。

【讨论】:

这不一定是真的。 JIT'r 通常会内联琐碎的属性。【参考方案6】:

在处理私有访问时,差异非常小。是的,存在性能损失(可能由 JIT 优化)发送属性表示方法调用,而不是直接地址访问。

使用属性的主要优点是允许更改实现而不更改所需的外部签名。由于这些是私有访问的,因此对实现的任何更改只会影响本地代码。

在与私人成员打交道时,除了您团队的约定之外,我认为财产没有任何优势。

【讨论】:

以上是关于私有字段和私有属性的区别的主要内容,如果未能解决你的问题,请参考以下文章

只读字段和私有 getter 属性之间的区别

Python面向对象之封装

我应该使用公共属性和私有字段还是公共字段来存储数据?

Python中的私有属性和私有方法

C# 自动属性来包装私有字段?

ios kvo能监听私有的属性吗