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