有什么理由在C#中使用私有属性?

我刚刚意识到C# 属性构造也可以与私有访问修饰符一起使用:

private string Password { get; set; } 

虽然这在技术上是有趣的,但我无法想象我什么时候可以使用它,因为私人领域涉及更less的仪式

 private string _password; 

我无法想象我什么时候需要能够在内部得到但没有设置设置,但没有得到一个私人领域:

 private string Password { get; } 

要么

 private string Password { set; } 

但也许有嵌套/inheritance类的用例,或者可能在一个get / set可能包含逻辑,而不是只是回报属性的值,虽然我倾向于保持属性严格简单,让明确的方法做任何逻辑,例如GetEncodedPassword()

有没有人在C#中使用私有属性是出于任何原因,还是仅仅是那些技术上可能的但很less使用的实际代码结构之一?

附录

很好的答案,阅读他们我把这些用途私有财产:

  • 当私人领域需要延迟加载
  • 当私人领域需要额外的逻辑或计算值
  • 因为私人领域可能难以debugging
  • 为了“向你自己提出合同”
  • 作为序列化的一部分内部转换/简化一个暴露的属性
  • 包装全局variables在你的类中使用

我使用它们,如果我需要caching一个值,并希望懒加载它。

 private string _password; private string Password { get { if (_password == null) { _password = CallExpensiveOperation(); } return _password; } } 

在我的代码中的主要用法是延迟初始化,正如其他人所说的。

私人财产超过领域的另一个原因是私人财产比私人领域更容易debugging。 我经常想知道这样一些事情:“这个领域意外地出现了问题,谁是第一个创build这个领域的调用者? 如果你可以在setter上放一个断点然后打开就更容易了。 你可以把日志logging在那里。 你可以把性能指标放在那里。 您可以放入在debugging版本中运行的一致性检查。

基本上,它归结为: 代码比数据更强大 。 任何让我编写我需要的代码的技术都是很好的。 属性不允许你在其中编写代码。

也许有一个嵌套/inheritance类的用例,或者可能是一个get / set可能包含逻辑,而不是只回馈属性的值

我个人甚至在我不需要属性的getter或setter逻辑的时候使用它。 使用一个属性,即使是一个私有属性,也可以帮助将来validation代码,以便以后可以将逻辑添加到getter中(如果需要)。

如果我觉得一个属性可能最终需要额外的逻辑,我有时会把它包装到一个私有属性中,而不是使用一个字段,所以我不必稍后更改我的代码。


在一个半相关的案例中(尽pipe与你的问题不同),我经常使用公共财产上的私人设置者:

 public string Password { get; private set; } 

这给你一个公共的getter,但保持setter私人。

懒惰初始化是一个可以整洁的地方,例如

 private Lazy<MyType> mytype = new Lazy<MyType>(/* expensive factory function */); private MyType MyType { get { return this.mytype.Value; } } // In C#6, you replace the last line with: private MyType MyType => myType.Value; 

然后你可以写: this.MyType遍地而不是this.mytype.Value并封装在一个地方懒惰地实例化的事实。

有一件令人遗憾的事情是,C#不支持将后台字段作为属性的范围(即在属性定义中声明它)来完全隐藏它,并确保它只能通过属性访问。

私人获取唯一属性的一个很好的用法是计算值。 有几次我有私人只读的属性,只是在我的types的其他领域的计算。 它不值得一个方法,其他类没有兴趣,所以私有财产。

我能想到的唯一一种用法

 private bool IsPasswordSet { get { return !String.IsNullOrEmpty(_password); } } 

我在序列化中使用它们,例如DataContractSerializer或protobuf-net,它支持这种用法( XmlSerializer不支持)。 如果您需要简化一个对象作为序列化的一部分,这是非常有用的:

 public SomeComplexType SomeProp { get;set;} [DataMember(Order=1)] private int SomePropProxy { get { return SomeProp.ToInt32(); } set { SomeProp = SomeComplexType.FromInt32(value); } } 

属性和字段不是一一对应的。 一个属性是关于一个类的接口(不pipe是在谈论它的公共接口还是内部接口),而一个属性是关于类的实现。 属性不应该被看作是暴露字段的一种方式,它们应该被看作是暴露类的意图和目的的一种方式。

就像您使用财产向您的消费者提供关于什么是您的课程的合同一样,您也可以出于非常类似的原因向您提供合同。 所以是的,我确实使用私有财产。 有时一个私有财产可以隐藏实现细节,如延迟加载,一个属性实际上是几个领域和方面的聚合,或者一个属性需要虚拟实例化与每个调用(认为DateTime.Now )。 当然,在class级的后端,甚至在你自己身上执行这个任务也是有意义的。

我一直在做的一件事是将“全局”variables/caching存储到HttpContext.Current

 private static string SomeValue{ get{ if(HttpContext.Current.Items["MyClass:SomeValue"]==null){ HttpContext.Current.Items["MyClass:SomeValue"]=""; } return HttpContext.Current.Items["MyClass:SomeValue"]; } set{ HttpContext.Current.Items["MyClass:SomeValue"]=value; } } 

我偶尔使用它们。 当你可以很容易地在属性中放置一个断点或者你可以添加一个日志logging语句等时,它们可以更容易地进行debugging。

如果您稍后需要以某种方式更改数据types,或者需要使用reflection,也可能会有用。

我使用私有属性来减less访问经常使用的子属性的代码。

  private double MonitorResolution { get { return this.Computer.Accesories.Monitor.Settings.Resolution; } } 

如果有许多子属性,这是有用的。

只有通过get / set方法修改成员,甚至私人修改成员才是常见的做法。 现在,逻辑背后的逻辑就是让你知道你的get / set总是以一种特殊的方式(比如,引发事件)行事,这似乎没有道理,因为这些不会被包含在属性scheme中。但老习惯很难

当存在与属性集相关的逻辑或者获得(认为惰性初始化)并且该属性在类中的一些地方被使用时,这是非常有意义的。

如果这只是一个直接的后盾领域? 没有什么可以成为一个很好的理由。