使用属性——避免将数据成员直接暴露给外界

转载 2006年06月16日 03:05:00

学习研究.NET的早期,经常碰到一些学习C#/.NET的朋友问,要属性这种华而不实的东西做什么?后来做项目时也时常接到team里的人的抱怨反馈,为什么不直接放一个public字段?如:

class Card
{ 
   public string Name;
}

而非要做一个private字段+public属性?

class Card
{
   private string name;
   public string Name
   {
      get { return this.name;}
      set { this.name=value;}
   }
}

我记得在早期的一个项目里,team中的一个朋友甚至厌烦了写private字段+public属性,尤其是碰到一大堆臃肿的data object class的时候,索性自己写了一个小工具,来提供一个类的字段名和类型,然后自动为该类生成相应的private字段+public属性。

我在编程的时候是个彻底的实用主义者,用稍微高雅一点的话说叫“不喜欢过度的设计”。如果真的像上面那样写Card,而且在将来没有什么改变的需求,我也不喜欢像上面第2段程序那样把事情故意搞得复杂。但如果从component的角度来讲,总有一些class是要供外部长久地使用,也潜在地在将来有被改变的需求。这时候,提供属性就很有必要了。

这就是这个Item试图要归纳的使用属性的理由:

1.

可以对赋值做校验、或者额外的处理

2.

可以做线程同步

3.

可以使用虚属性、或者抽象属性

4.

可以将属性置于interface中

5.

可以提供get-only或者set-only版本,甚至可以给读、写以不同的访问权限(C# 2.0支持)

个人感觉3、4条是属性最大的优点,可以填补没有“虚字段”或“抽象字段”的缺憾,在设计组件的时候非常有用,也体现了C#这样的component-oriented语言的精神内涵。

但如果没有上述理由,而且日后对程序做大的改动可能性比较小时,我想也大可不必非要把每个public字段都要变成属性。比如在设计一些轻型的struct,用于互操作的时候,直接使用public字段没什么不好。所以,感觉本条目Bill Wagner先生使用“Always Use Properties Instead of Accessible Data Members”显得太过强硬。

其实,这里的讨论也表明阅读《Effective C#》一书时需要注意的地方,即Effective原则并不是放之四海而皆准的。不同的项目(组件化、复用程度较高的项目?还是“一次编写、N年都run”的项目),不同的角色(类库/组件开发人员?还是应用程序开发人员?),有着不同的Effective准则。事实上,书中很多Items都是从类库/组件开发人员的角度来考虑的。

关于属性的性能问题需要谈一点,如果仅仅是简单地以存取模式来使用属性,在相当程度上是没有性能损失的。因为在JIT编译过程中已经做了inline的处理。不过inline处理还是有一些基本的条件,有些情况下JIT编译器不会inline,比如虚调用,方法的IL代码长度过长(目前CLR的规定是超过32bytes为代码长度过长),有复杂的控制流逻辑,有异常处理等。这些条件都是要么根本不能使用inline(比如虚属性),要么inline的代价太大,容易导致代码的bloat,要么是inline起来很费时间——已经丧失了inline的意义,因为.NET的inline机制发生在JIT过程中。使用属性有个别让人感觉不舒服的地方,比如它影响开发人员的开发效率,但对代码运行的效率不产生影响。

 

相关文章推荐

【C#高效编程50例】条目1:使用属性而不是可访问的数据成员

书名:《C#高效编程 改进C#代码的50个行之有效的方法》 条目1 使用属性而不是可访问的数据成员 1 属性格式 private string _scustomerName = ...
  • gjban
  • gjban
  • 2015-09-30 10:34
  • 361

Effective C# 原则1:尽可能的使用属性(property),而不是数据成员(field)

http://www.cnblogs.com/WuCountry/archive/2007/02/10/646756.html Effective C# 原则1:尽可能的使用属性(property),...

effective C++笔记之条款20、21:避免public接口出现数据成员、尽可能使用const

条款20: 避免public接口出现数据成员   l        如果接口里存在数据成员,用户每次访问类的成员时候会想是该用括号还是不该用括号。如果每个成员都是函数,就不用多想了。 l ...

数据成员与属性

class Stud {   public string name; } 数据成员//data member\field class stud {   public string nam...

定义const对象而产生的常数据成员与直接定义const数据成员在编译器编译时候的区别

《C++面向对象程序设计(第2版)》P92“const数据成员可以被非const的成员函数引用”与 “const对象不能被非const的普通成员函数引用”是否矛盾??《C++面向程序设计(第2版)》P...

Data 语意学 —— 数据成员的绑定、布局与存取

本节简单介绍了类对象中数据成员的绑定、布局以及存取。

第十二章 类 —— 第二节 隐含的this指针和mutable可变数据成员

第十二章 类 关于C++的几篇博客,参考人民邮电出版社的《C++ Primer 中文版》一书。 本章节介绍类的隐含this指针和mutable可变数据成员。 第二节 隐含的this指针和mu...

第五周上机实践项目2——对象作为数据成员

问题及代码 /* * Copyright (c) 2015, 烟台大学计算机学院 * All rights reserved. * 文件名称:test.cpp * 作 者:辛彬 * ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)