【问题标题】:How do properties provide encapsulation?属性如何提供封装?
【发布时间】:2026-01-12 02:15:01
【问题描述】:

我开始学习C#,但我不明白当set方法不做任何操作、验证等时,属性是如何提供封装的。我的代码:

class SitePage {
private string _specialString;
public string SpecialString
{
get { return _specialString; }
set { _specialString = value; }
}}

这里,我们不使用字段 _specialString,而是使用属性 SpecialString。基本上,我们不是公开字段,而是公开属性。为什么隐藏字段但将属性暴露给客户端类?

【问题讨论】:

    标签: c# c#-4.0 c#-3.0 c#-2.0


    【解决方案1】:

    当您使用 c# 属性时,编译器会在后台自动创建该字段。因此,每当您获取该属性时,它都会使用一种方法来检索存储在基础字段中的值。当您设置该属性时,它正在设置该基础字段。

    当您需要一个简单的实现时,使用 {get;set;} 语法本质上是一种捷径。

    真正的好处是当您需要控制它如何获取或设置这些值时。

    例如,您可以使用以下语法:

    public SpecialString{get;private set;}
    

    这将使您可以从类外部检索属性的值,但您只能使用类自己的内部逻辑在内部设置值。

    或者你可以这样做:

    private string _specialString;
    public string SpecialString{
        get;
        set{
            if(value.Length < 5)
            {
                throw new Exception();
            }
            else
            {
                this._specialstring = value;
            }
    }
    

    或者您可以在获取或设置某个属性时触发其他方法。将物业视为看门人。您可以设置任何您想要的规则,以便让数据传入或传出。

    【讨论】:

      【解决方案2】:

      这个想法几乎是您通常想要退回一份副本。当您处理税务信息等敏感数据时,这一点变得非常重要。您不希望任何人或任何事物能够直接访问某人的税务信息。许多程序不需要这样的系统,但仍然被认为是好的做法,因为它让你养成了这种习惯。

      通过这样的中介可以确保所有事情都是经过深思熟虑的,并允许您进行一些错误检查,仅更改它,而不是强制它在文件中本地运行。例如,如果你有一个永远不应该为负数的数字,你可以在你的 set 方法中包含一个错误检查,而不是在你使用变量的任何地方都这样做。

      如果您需要更多详细信息或示例,请告诉我。我觉得我解释得不是很好,但我希望我解释得足够好,让您大致了解为什么要这样编码。

      【讨论】:

        【解决方案3】:

        通常,属性构成公共接口,字段是支持数据。你也可以这样写一个自动实现的属性:

        public string SpecialString { get; set; }
        

        这样,编译器将自动构建支持字段。

        将公共属性作为私有支持字段的接口还有其他优点,例如当您想查看值是否已更改并引发事件时。

        private string _specialString;
        
        public string SpecialString
        {
          get
          {
            return _specialString;
          }
          set
          {
            if (_specialString != value)
            {
              _specialString = value;
              OnValueChanged();
            }
          }
        }
        

        【讨论】: