C# 将受保护字段设为私有,添加属性——为什么?
在 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; } }
}
两个问题:
- 我是否正确理解了该建议希望我做什么(从代码角度来看)?
- 为什么它要我这样做?
In Visual Studio 2008 Team System, I just ran Code Analysis (from the Analyze menu) on one of my C# projects. One of the warnings produced was the following:
Microsoft.Design : Because field 'Connection._domain' is visible outside of its declaring type, change its accessibility to private and add a property, with the same accessibility as the field has currently, to provide access to it.
It's referring to the following field:
public abstract class Connection
{
protected string _domain;
}
I don't understand the reasoning behind the suggestion. This is what I think it wants me to do:
public abstract class Connection
{
private string _domain;
protected string Domain { get { return _domain; } set { _domain = value; } }
}
Two questions:
- Did I understand correctly what the suggestion wants me to do, code-wise?
- Why does it want me to do this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
是的,我认为您理解正确 - 尽管在 C# 的更高版本中,有更简洁的编写方式:
为什么?这都是关于封装的。如果您按照建议进行操作,则稍后可以更改 Domain 属性的定义,而不会影响使用该属性的任何调用代码。由于您的类是公共的,并且可能会被您未编写的代码调用,因此这可能非常重要。
Yes, I think you understood correctly - although in later versions of C#, there's a more concise way to write it:
Why? It's all about encapsulation. If you do as it suggests, you can later change the definition of the Domain property without affecting any calling code that uses that property. Since your class is public, and might conceivably be called by code that you didn't write, that's potentially quite important.
这是因为,如果您将来想要将该字段更改为属性,您将破坏依赖于它的任何其他程序集。
最好将所有字段保持私有并将它们包装在属性中,以便您可以选择在将来添加验证或其他逻辑,而无需重新编译类的所有使用者(或在本例中为继承者)。
This is because if you ever wanted to change the field to a property in the future you would break any other assemblies that depend on it.
It is good practice to keep all fields private and wrap them in properties so that you have the option of adding validation or other logic in the future without recompiling all consumers (or in this case inheritors) of your class.
是的。这就是建议。您不应该拥有比作为直接实例字段公开的私有更高的可访问性。
这是 OOD 的主要原则之一 - 封装也称为“数据隐藏”。
Yep. That's the suggestion. You shouldn't have any accessibility higher than private exposed as direct instance fields.
It's one of the main principles of OOD - encapsulation also referred to as 'data-hiding'.
_domain
是有关您的对象的数据。您应该提供一个接口供他们访问它,而不是直接公开它以便任何客户端都具有未经过滤的访问权限。实际上,这可能会向设置器添加验证,以便它不能设置为任何值。如果您是唯一一个编写代码的人,因为您知道 API 是如何工作的,那么这可能看起来很愚蠢。但尝试从大型企业层面考虑问题,最好有一个 API,这样您的对象就可以被视为完成任务的盒子。您可能会说您永远不需要向该对象添加验证之类的东西,但这样做是为了保持它的可能性,并且也是为了保持一致。_domain
is data about your object. Rather then exposing it directly so that any client has unfiltered access, you should provide an interface for them to access it. Practically this might be adding validation to the setter so that it can't be set to any value. It might seem silly if you are the only one writing code because you know how your API works. But try to think about things on a large enterprise level, it is better to have an API so that your object can be seen as a box that accomiplishes a task. You might say you will never have the need to add something like validation to that object, but things are done that way to hold for the possibility of it, and also to be consistent.你的翻译是正确的。对于使用“受保护”属性可以提出与使用“公共”属性而不是直接公开成员变量相同的论点。
如果这只会导致简单的 getter 和 setter 的激增,那么我认为对代码可读性的损害超过了将来能够更改代码的好处。随着 C# 中编译器生成属性的发展,这还不算太糟糕,只需使用:
Your translation is correct. The same argument for can be made for using 'protected' properties as can be made for using 'public' properties instead of exposing member variables directly.
If this just leads to a proliferation of simple getters and setters then I think the damage to code readablity outweighs the benefit of being able to change the code in the future. With the development of compiler-generated properties in C# this isn't quite so bad, just use:
回答你的问题......是的。
但是,我只会使用自动属性语法:
In answer to your question... yes.
However, I would just use the auto-property syntax:
基本上,属性提供的不仅仅是返回或设置成员。它们允许您添加可以验证正确的输入格式、范围验证等的逻辑。
从链接中选择的答案说得最好,“属性提供封装。您可以在属性的代码中封装任何需要的验证/格式化/转换这对于领域来说是很难做到的。”
http://social. msdn.microsoft.com/Forums/en-IE/netfxbcl/thread/985f4887-92ae-4ec2-b7ae-ec8cc6eb3a42
Basically, properties provide more than returning or setting a member. They allow you to add logic that could verify a proper input format, range validation, etc.
The selected answer from the link puts it best, "Properties provide encapsulation. You can encapulate any needed validation/formating/conversion in the code for the property. This would be difficult to do for fields."
http://social.msdn.microsoft.com/Forums/en-IE/netfxbcl/thread/985f4887-92ae-4ec2-b7ae-ec8cc6eb3a42
除了此处提到的其他答案之外,以下划线开头的公共/受保护成员不是 符合 CLS,因为 .NET 语言不要求支持带前导下划线的成员,因此使用其他 .NET 语言从您的类继承的人可能无法访问该特定的受保护成员。
我知道,它可能不适用于您,但这可能是代码分析警告的部分原因。
In addition to the other answers mentioned here, public/protected members that begin with an underscore are not CLS-compliant, in that there is no requirement for .NET languages to support members with leading underscores, so someone inheriting from your class in a different .NET language may not be able to access that particular protected member.
I know, it probably doesn't apply to you, but it might be part of the reason for the code analysis warning.