5

在 Visual Studio 2008 Team System 中,我刚刚对我的一个 C# 项目运行了代码分析(从分析菜单中)。产生的警告之一如下:

Microsoft.Design :因为字段“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; } }
}

两个问题:

  1. 我是否正确理解了建议要我做什么,代码方面?
  2. 为什么它要我这样做?
4

8 回答 8

13

是的,我认为您理解正确 - 尽管在 C# 的更高版本中,有一种更简洁的方式来编写它:

public string Domain { get; set; }

为什么?这都是关于封装的。如果您按照建议进行操作,您可以稍后更改域属性的定义,而不会影响使用该属性的任何调用代码。由于您的课程是公开的,并且可能会被您未编写的代码调用,因此这可能非常重要。

于 2009-11-09T20:06:14.873 回答
3

这是因为如果您将来想将该字段更改为属性,您将破坏任何其他依赖它的程序集。

最好将所有字段保持私有并将它们包装在属性中,以便您可以选择在将来添加验证或其他逻辑,而无需重新编译类的所有使用者(或在这种情况下为继承者)。

于 2009-11-09T20:06:36.620 回答
2

是的。这就是建议。您不应该有任何比作为直接实例字段公开的私有更高的可访问性。

这是 OOD 的主要原则之一——封装也称为“数据隐藏”。

于 2009-11-09T20:06:24.590 回答
2
  1. 是的,您确实明智地纠正了问题代码。
  2. 这是关于封装的。_domain是关于您的对象的数据。与其直接公开它以使任何客户端都具有未过滤的访问权限,不如为他们提供访问它的接口。实际上,这可能会向设置器添加验证,以便不能将其设置为任何值。如果你是唯一一个编写代码的人,因为你知道你的 API 是如何工作的,这可能看起来很傻。但是尝试在大型企业级别上考虑问题,最好有一个 API,以便您的对象可以被视为完成任务的盒子。您可能会说您永远不需要向该对象添加诸如验证之类的东西,但是这样做是为了保持它的可能性,并且也是为了保持一致。
于 2009-11-09T20:06:28.117 回答
2

你的翻译是正确的。使用“受保护”属性可以使用与使用“公共”属性而不是直接公开成员变量相同的参数。

如果这只是导致简单的 getter 和 setter 的扩散,那么我认为对代码可读性的损害超过了将来能够更改代码的好处。随着 C# 中编译器生成属性的发展,这并不是那么糟糕,只需使用:

protected string Domain { get; set; }
于 2009-11-09T20:08:10.370 回答
0

在回答你的问题......是的。

但是,我只会使用自动属性语法:

public abstract class Connection
{
    protected string Domain { get; set; }
}
于 2009-11-09T20:09:44.117 回答
0

基本上,属性提供的不仅仅是返回或设置成员。它们允许您添加可以验证正确输入格式、范围验证等的逻辑。

从链接中选择的答案说得最好,“属性提供封装。您可以在属性的代码中封装任何需要的验证/格式化/转换。这对于字段来说很难做到。”

http://social.msdn.microsoft.com/Forums/en-IE/netfxbcl/thread/985f4887-92ae-4ec2-b7ae-ec8cc6eb3a42

于 2009-11-09T20:13:30.630 回答
0

除了此处提到的其他答案之外,以下划线开头的公共/受保护成员不符合 CLS,因为 .NET 语言不需要支持带前导下划线的成员,因此有人从您的类继承了不同的.NET 语言可能无法访问该特定受保护成员。

我知道,它可能不适用于您,但这可能是代码分析警告的部分原因。

于 2009-11-09T22:05:17.660 回答