C# 将受保护字段设为私有,添加属性——为什么?
-
19-09-2019 - |
题
在 Visual Studio 2008 Team System 中,我刚刚对我的一个 C# 项目运行了代码分析(从“分析”菜单)。产生的警告之一如下:
微软设计:由于字段“Connection._domain”在其声明类型之外可见,因此将其可访问性更改为私有,并添加一个属性(与该字段当前具有相同的可访问性)以提供对其的访问。
它指的是以下字段:
public abstract class Connection
{
protected string _domain;
}
我不明白该建议背后的原因。这就是我认为它希望我做的事情:
public abstract class Connection
{
private string _domain;
protected string Domain { get { return _domain; } set { _domain = value; } }
}
两个问题:
- 我是否正确理解了该建议希望我在代码方面做什么?
- 为什么它要我这样做?
解决方案
是的,我认为你理解正确 - 尽管在 C# 的更高版本中,有更简洁的编写方式:
public string Domain { get; set; }
为什么?这都是关于封装的。如果您按照建议进行操作,则稍后可以更改 Domain 属性的定义,而不会影响使用该属性的任何调用代码。由于您的类是公共的,并且可能会被您未编写的代码调用,因此这可能非常重要。
其他提示
是的。这就是建议。您不应该拥有比作为直接实例字段公开的私有更高的可访问性。
这是 OOD 的主要原则之一 - 封装也称为“数据隐藏”。
- 是的,您确实纠正了问题代码。
- 这是关于封装的。
_domain
是有关您的对象的数据。您应该提供一个接口供他们访问它,而不是直接公开它以便任何客户端都具有未经过滤的访问权限。实际上,这可能会向设置器添加验证,以便它不能设置为任何值。如果您是唯一一个编写代码的人,因为您知道 API 是如何工作的,那么这可能看起来很愚蠢。但尝试从大型企业层面考虑问题,最好有一个 API,这样您的对象就可以被视为完成任务的盒子。您可能会说您永远不需要向该对象添加验证之类的东西,但这样做是为了保持它的可能性,并且也是为了保持一致。
你的翻译是正确的。对于使用“受保护”属性可以提出与使用“公共”属性而不是直接公开成员变量相同的论点。
如果这只会导致简单的 getter 和 setter 的激增,那么我认为对代码可读性的损害超过了将来能够更改代码的好处。随着 C# 中编译器生成属性的发展,这还不算太糟糕,只需使用:
protected string Domain { get; set; }
这是因为,如果您将来想要将该字段更改为属性,您将破坏依赖于它的任何其他程序集。
最好将所有字段保持私有并将它们包装在属性中,以便您可以选择在将来添加验证或其他逻辑,而无需重新编译类的所有使用者(或在本例中为继承者)。
回答你的问题...是的。
但是,我只会使用自动属性语法:
public abstract class Connection
{
protected string Domain { get; set; }
}
基本上,属性提供的不仅仅是返回或设置成员。它们允许您添加可以验证正确的输入格式、范围验证等的逻辑。
从链接中选择的答案说得最好:“属性提供封装。您可以在属性的代码中封装任何所需的验证/格式化/转换。这对于田间来说很难做到。”
http://social.msdn.microsoft.com/Forums/en-IE/netfxbcl/thread/985f4887-92ae-4ec2-b7ae-ec8cc6eb3a42
除了此处提到的其他答案之外,以下划线开头的公共/受保护成员不包括在内 符合 CLS 标准, ,因为 .NET 语言不需要支持带有前导下划线的成员,因此使用不同 .NET 语言从您的类继承的人可能无法访问该特定的受保护成员。
我知道,它可能不适用于您,但这可能是代码分析警告的部分原因。