【问题标题】: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();
}
}
}