【问题标题】:Backing a public property with a private property?用私有财产支持公共财产?
【发布时间】:2026-01-18 04:50:01
【问题描述】:

我在看一些代码,发现了这种模式:

private string text { get; set; }
public string Text
{
    get
    {
        return text;
    }
    set
    {
        text= value;
        RaisePropertyChanged("Text");
    }
}

我通常只是用私有字段支持我的公共属性。

是否有任何理由应该由这样的私有财产支持财产?我的直觉是说它不应该,这应该由一个字段来支持,对吗?有什么技术原因可以用来备份吗?

【问题讨论】:

  • 没有理由这不起作用。你遇到过这个问题吗?
  • 这里没有技术限制,尽管我认为在这种情况下最好的做法是始终使用字段。
  • 好吧,我看不出这样做的充分理由,但从技术上讲,它没有理由不工作。可能会涉及更多开销,但是如果您这样做(必须比较 IL 输出),这就是为什么我会采用使用变量而不是另一个属性的经典方式。也可能是优化器将私有通用属性变成了一个字段?
  • 这个背后似乎有很多意见。至于技术原因,不,没有技术原因无法做到这一点。一个人是否应该这样做真的将取决于正在实施的内容。该类可能足够复杂,以至于私有成员可以从属性背后的抽象中受益。公开类状态的公共属性可能想要使用该抽象。这种方法的好处是根据具体情况而定。
  • 我认为在大多数情况下,无论哪种方式都应该没问题。将它作为一个属性使其更加灵活,但它实际上会产生影响的实例很少,您不必担心使用哪个。

标签: c#


【解决方案1】:

典型的情况是当你有一个原始数据(没有任何转换的数据)和相同的数据,但友好地表示:

  private String m_RawText;

  // Text as it's obtained from, say, database 
  private string rawText { 
    get {
      if (null == m_RawText)
        m_RawText = ReadValueFromDataBase();

      return m_RawText;
    } 
    set {
      if (m_RawText != value) {
        UpdateValueInDataBase(value);

        m_RawText = value;
      }
    }  
  }

  // Friendly encoded text, for say UI
  public string Text {
    get {
      return EncondeText(rawTex);
    }
    set {
      rawText = DecodeText(value);

      RaisePropertyChanged("Text");
   }
 }  

 // Here we want rawText
 public void PerformSomething() {
   String text = rawText; // we want raw text...
   ...
 } 

 // And here we prefer Text
 public override String ToString() {
   return String.Fromat("Text = {0} ", Text, ...)
 } 

【讨论】:

  • 这仍然没有回答 OP 的问题,编辑后。可以使用字段或属性来完成完全相同的原始数据存储。
  • 我认为这个例子有点令人困惑(至少对我来说),但我同意这里答案的整体精神。即使在中等复杂的场景中,一个类也可以很容易地拥有一个私有成员,该成员由于各种原因而被抽象在一个属性后面。读取或写入该成员时要调用的一些常见逻辑,即使它只是私下调用过。在公开对象的状态时,公共属性可能也希望利用相同的公共逻辑,因此将使用私有属性作为其支持数据而不是原始字段。