带访问器的公共变量与私有变量

时间:2020-03-06 15:05:21  来源:igfitidea点击:

有没有其他人看到人们这样做:

private string _name;
public string Name{ get{ return _name; } set{ _name = value;}}

我了解使用访问器,如果我们要对如何设置它进行某种控制,或者在有访问时对其执行某种功能。但是,如果我们只是要这样做,为什么不只是从头开始公开变量呢?我想念什么吗?

解决方案

准备。我们永远不知道何时要删除集合访问器,何时在setter中执行其他操作或者更改get的数据源。

可公开访问的成员通常应该是方法而不是字段。这只是一个好习惯,并且该实践可以确保对象的封装状态始终处于控制之下。

这个想法是,如果我们使用访问器,则可以在不更改API的情况下更改基础实现。例如,如果我们决定在设置名称时还需要更新文本框或者其他变量,则无需更改任何客户端代码。

如果在程序集A中使用属性定义公共接口,则可以在程序集B中使用此接口。

现在,我们可以更改属性的实现(也许从数据库中获取值,而不是将其存储在字段中)。然后,我们可以重新编译程序集A,并替换较旧的程序集。程序集B可以进行得很好,因为接口不会更改。

但是,如果我们最初是从公共领域开始的,并且认为这不合适,并且想要更改实现并将其转换为属性,则这意味着我们必须进行更改程序集A的公共接口。该接口的所有客户端(包括程序集B)也必须重新编译并替换才能使用此新接口。

因此,最好先从属性开始。这封装了该属性的实现,使我们将来可以自由更改它,而不必担心使用程序集A的世界上有哪些客户端(包括程序集B)。利用程序集A,更改接口将破坏所有客户端。如果公司中的另一个团队或者其他公司使用了它们,那么如果我们通过更改界面来破坏它们的组件,他们将不高兴!

良好的编程习惯。这是非常常见的模式,适合OO设计方法。通过公开一个公共字段,我们可以公开如何存储该数据的内部信息。相反,使用公共属性可以使我们更加灵活地更改内部存储数据的方式,并且不会破坏公共接口。它还使我们可以更好地控制访问数据时发生的情况(延迟初始化,空检查等)。

如果将成员设为公共字段,则以后不能在不更改类接口的情况下将其重构为属性。如果从一开始就将其公开为属性,则可以对所需的属性访问器函数进行任何更改,并且类的接口保持不变。

请注意,从C3.0开始,我们可以在不创建后备字段的情况下实现属性,例如:

public string Name { get; set; }

这消除了最初不将公共字段实现为属性的唯一理由。

变量是类实现的一部分。属性在逻辑上代表了它的接口。使用C3.0,自动实现的属性使从一开始就很容易做到。

在此主题的文章中,我对此进行了更多思考,包括从变量更改为属性的各种方式不仅破坏二进制兼容性,而且破坏源代码兼容性。

对于封装,不建议使用公共字段。

http://my.safaribooksonline.com/9780321578815/ch05lev1sec5?displaygrbooks=0

就像克里斯·安德森(Chris Anderson)在本书的后面所说的那样,如果呼叫者对字段与属性的差异视而不见,那将是理想的选择。

为了保持高度的可扩展性而又无需重新编译所有程序集,我们希望使用公共属性作为访问器。通过遵循描述对象如何交换数据的"合同"或者定义的机制,一系列规则将得到落实。该合同通过接口强制执行,并由继承此接口的类的getter和setter履行。

稍后,如果我们要从该接口创建其他类,则可以灵活使用属性来遵守合同,但是由于我们是通过getter和setter提供数据的,因此组装数据的实现或者过程可以满足任何要求希望,以及它返回"合同"所期望的类型。

可能值得注意的是,.NET中的DataBinding也拒绝处理公共字段并要求属性。因此,这可能是另一个原因。