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

41

使用私有属性和使用私有字段有什么区别?

private String MyValue { get; set; }

// instead of

private String _myValue;

public void DoSomething()
{
   MyValue = "Test";

   // Instead of

   _myValue = "Test";
}

这会有性能问题吗?还是只是命名约定?

6个回答

29

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


9
如果你决定需要除了逻辑简单的一行getter和setter之外的东西,将一个字段重构为属性是不需要任何成本的。 - recursive
1
你有关于那个答案的任何参考资料吗?我们现在正在团队讨论中。我更喜欢使用props,但是我的一个同事倾向于使用fields来处理私有内容,并将属性视为向外部通信的工具。因此,根据他们的观点,私有属性没有意义。对我来说,它确实有意义,因为类与其属性一起工作,并且实际上并不关心这些属性是公共的还是私有的... - Konrad Viltersten
1
@recursive 嗯...这是有成本的。重构需要时间。 :) - Konrad Viltersten
自从我上次发表评论以来,我积累了十年或二十年的经验:我认为这两种模式都有优点。字段:可以用作“ref”。编译器优化的可能性更大。属性:可以参与接口,并且可以在不破坏其他程序集中的调用方的情况下进行更新。 - recursive

24

你可以从属性(私有、公共等)中获得的最大好处是它可以生成计算值而不是设置固定值。例如:

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

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


11

很少有情况需要将属性设置为私有。仅仅是为了完整性才提供了属性的私有权限。而且,如果你的属性只是用来获取/设置字段的值,那么由于 JIT 编译器会进行内联处理,所以性能不会有任何差别。


5
除了已经回答过的性能、语义和完整性之外,我还见过一种使用私有属性而不是私有字段的有效情况:
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,但我们可能也想进行验证检查。一个父级是否能够作为其子级之一被添加?
为了解决这个问题,您可以将其作为属性并执行循环引用检查。

1

属性访问会稍微慢一些,因为它会调用getter/setter。好处是你可以进行数据验证,如果你将属性更改为protected,那么这种验证可以传递给继承者。


9
这并不一定是正确的。JIT编译器通常会内联轻量级属性。 - JaredPar

0

在处理私有访问时,差异非常小。是的,会有性能损失(可以通过JIT进行优化),因为属性表示方法调用,而不是直接地址访问。

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

在处理私有成员时,我认为除了团队惯例之外,没有从属性中获得的优势。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接