欢迎光临散文网 会员登陆 & 注册

第 92 讲:C# 3 之自动属性

2022-03-05 12:50 作者:SunnieShine  | 我要投稿

如果说 C# 2 的诞生是为了修补和扩充 C# 原生语法的话,那么 C# 3 就是为了优雅而存在。今天要说的语法是大大简化了书写的代码量,它叫自动属性(Auto-Implemented Properties)。可以从英语发现,这个词组翻译成“自动实现的属性”更为合适。

Part 1 引例

假设我们还是和以前一样,实现一个学生类型,它包含姓名、年龄和性别三个属性的话,那么原本代码应该这么写:

可以从代码发现,属性的封装模式都是完全一致的,可 C# 原生语法和 C# 2 却非得要求我写这么一长串。C# 3 考虑到了这个问题,于是开始优化和简化代码,做到极致。

C# 3 开始引入了一个全新的属性的语法:自动属性。它让你的属性声明,长得更像抽象属性的语法,只是不带 abstract 关键字:

是的,这样书写代码就 OK 了。这就是自动属性,编译器会自动把这段代码翻译成上面的完整版本,也没有任何的区别。本文结束。

Part 2 如何区分接口里的属性、抽象属性和自动属性语法?

可以从语法里看出,这个语法完全就是直接照搬了抽象属性的语法,还有接口里的属性的声明的语法。因为只有抽象属性和接口里的属性,getset 关键字后面才会直接跟分号结尾。因为它在语法规定上是抽象的,抽象的成员是不能有实现的。因此,C# 的抽象属性和接口内属性,都是这样的语法。

可问题就在于,现在有了这个新语法后,这个语法长相跟抽象属性一点区别都没有,那么怎么区分呢?

其实,很好区分。两点:

  1. 如果是接口内属性,那么一定不是自动属性;

  2. 如果属性有 abstract 修饰符,那么也一定不是自动属性。

我们现场举例。

很轻松地可以了解到,Base 类型的 PropertyDerived2 类型的 PropertyProperty2 都是有 abstract 修饰符的,因此它们都不是自动属性,而是抽象属性的语法;而 Derived 里的 Property 属性,以及 Derived3 类型里的 Property2 因为没有 abstract 修饰符,还都是在类里(而不是接口类型里),因此它们都是自动属性。

Part 3 必须同时有 getter 和 setter 才能使用自动属性

请注意前文给的代码。Derived2 类型里的 Property2 抽象方法只要求实现 getter,因此重写的时候你只能对属性给出 getter,而不能包含 setter。但是,自动属性目前仅允许既有 getter 又有 setter 的属性这么省略。正是因为有这个限制,因此第 23 行的只有 getter 的属性必须完整写出取值操作的代码。

可为什么这样限制呢?原因很简单:因为设计代码的时候,也不会有人考虑把一个东西通过属性只读取出来。实用的属性应该是 getter 和 setter 都有的情况,这样我可以避免自己声明构造器的同时,来完成初始化操作,使用前面我们才学过的语法:对象初始化器。

对象初始化器的操作就只需要保证对象的属性和字段能够赋值进去。那么,我使用自动属性的语法来完成属性的声明,难道就不叫属性了吗?当然叫。而且不但叫属性,还因为同时带有 getter 和 setter 的关系,可以允许我们使用对象初始化器的语法来完成初始化,可以更灵活的给属性赋值。

对象初始化器的赋值是可选的(Optional)。换句话说,对象初始化器并没有要求你必须对所有属性全部都初始化,而你要做的,只是选取你必须初始化的部分来初始化就可以了:

不赋值,就保持属性对应的那个底层字段是默认数值,仅此而已。所以,如下的语法里,可以通过注释了解这个写法的正确性。

总之,没 abstract 修饰的属性都是自动属性(只要没放在接口里),而既然是自动属性,那么它就只允许同时包含 getter 和 setter 的情况;而有 abstract 修饰的属性由于不是自动属性,因此不论只有 getter、只有 setter、还是都有,它们都是可以的。

Part 4 自动属性的存在扩充了数据成员的范围

C# 3 诞生的自动属性除了简化代码的意义以外,它还改变了“数据成员”这个早就接触过的词语的定义范畴。以前我们数据成员只包含字段,因为只有字段才是真正存储数据的。在那个时候,属性只用来封装字段,因此只有字段是数据成员。现在 C# 3 诞生的特性自动属性可以允许我们不再书写出背后的字段,而是简写为属性本身。所以,这样的自动属性实际上也暗含了一种存储数据数值的机制。因此,我们从 C# 3 开始,就可以把自动属性划到数据成员的行列里来。

现在,数据成员就包含字段和自动属性两种情况了。


第 92 讲:C# 3 之自动属性的评论 (共 条)

分享到微博请遵守国家法律