24

有没有其他人见过人们这样做:

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

如果您要对它的设置方式进行某种控制或在有获取时对其执行某种功能,我理解使用访问器。但是,如果您只是要这样做,为什么不一开始就将变量设为 public 呢?我错过了什么吗?

4

10 回答 10

36

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

请注意,从 C# 3.0 开始,您可以在不创建支持字段的情况下实现属性,例如:

public string Name { get; set; }

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

于 2008-10-03T18:27:47.313 回答
13

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

现在,您可以更改属性的实现(也许从数据库中获取值而不是将其存储在字段中)。然后您可以重新编译程序集 A,并替换旧的程序集。程序集 B 可以正常运行,因为界面不会改变。

但是,如果您最初是使用公共字段开始的,并且认为这不合适并想要更改实现并且需要将其转换为属性,那么这意味着您必须更改程序集 A 的公共接口。该接口的任何客户端(包括程序集 B)也必须重新编译和替换才能使用这个新接口。

所以,你最好从一个属性开始。这封装了属性的实现,让您可以在未来自由更改它,而不必担心使用程序集 A 已经存在哪些客户端(包括程序集 B)。因为,如果世界上已经存在任何客户端使用程序集 A,更改接口会破坏所有客户端。如果它们被您公司的另一个团队或其他公司使用,那么如果您通过更改您的界面来破坏他们的程序集,他们将不高兴!

于 2008-10-03T18:26:02.260 回答
6

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

于 2008-10-03T18:23:38.100 回答
6

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

于 2008-10-06T13:46:04.790 回答
3

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

于 2008-10-03T18:27:34.007 回答
2

变量是类实现的一部分。属性更合乎逻辑地表示它的接口。在 C# 3.0 中,自动实现的属性让这一切从一开始就变得轻而易举。

在一篇关于该主题的文章中,我已经写了更多关于此的想法,包括从变量更改为属性的各种方式不仅会破坏二进制兼容性,还会破坏源代码兼容性。

于 2008-10-03T19:05:11.260 回答
0

准备。您永远不知道什么时候需要删除 set 访问器,在 setter 中执行其他操作,或更改 get 的数据源。

于 2008-10-03T18:19:22.947 回答
0

可公开访问的成员通常应该是方法而不是字段。这只是一种很好的做法,这种做法可以帮助您确保对象的封装状态始终在您的控制之下。

于 2008-10-03T18:20:35.877 回答
0

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

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

正如克里斯安德森在本书后面所说的那样,如果调用者对字段与属性的区别视而不见,那将是理想的。

于 2008-10-03T19:18:20.550 回答
0

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

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

于 2008-10-03T19:33:39.440 回答