zoukankan      html  css  js  c++  java
  • 《Effective C#中文版:改善C#程序的50种方法》——Effective C# 原则1:尽可能的使用属性(property),而不是数据成员(field)

    我们的目标:尽可能编写出运行效率更高,更健壮,更容易维护的C#代码

    原则一:尽可能的使用属性(property),而不是数据成员(field)。

    Always use properties instead of accessible data members.

    出于以下几点原因,请在设计类时,尽可能的使用属性,而不是成员。

    1、.Net对属性的支持远远大于对成员的支持,你可以对属性进行数据绑定,设计时说明等很多数据成员不被支持的内容。看看.net里的属性面板,你会明白的。

    2数据安全性检测;

    属性本质上是两个函数,只是因为C#的特殊语法,但我们可以像访问成员一样的访问它。因此我们可以在属性设计上添加更多更灵活的内容,对属性进行管理。其中对属性数据的检测是其中之一。

    在对数据检测时,如果发现数据不满足条件,最好以抛出异常的形式来解决,千万不要设置默认值,这是很危险的事情。例如:

    public string Name{

           get{

                  if(this._Name==null){

                         return “NoName”;

    }else{

           return this._Name;

    }

    }

    set{

           if(value==null){

                  this._Name = “NoName”;

    }else if(value.Length<=10){

           this._Name = value;

    }else{

           this._Name = value.SubString(0,10);

    }

    }

    }

    看上去很不错不是吗?请马上动手修改你的代码吧,上面的代码是很危险的!或者你还不明白,明明对数据进行了安全检测,为什么还是危险的呢?试想这样的情况,有两个实例o1o2, o1Namenull,我们做了这样的事:o2.Name = o1.Name;

    结果是什么?o2.Name”NoName”,而在本质上,o1o2Name是根本不相等的。这会对后面的程序运行带来很大的麻烦。请以抛出异常的形式来解决数据不满足条件时的问题。

    3、线程同步

    对实例的属性可以进行线程同步,而与访问者无关。例如:

    public string Name{

           set{

                  lock(this){

                         //…

    }

    }

    }

    当然,你完全可以在类的外面进行线程同步,但那样的工作量远比上面的方法大得多。推荐你使用上面的方法进行线程同步,如果要对静态成员同步,请用lock(typeof(MyClass))方法。

    4属性可以是抽象的,而数据成员不能是抽象的,这为我们设计出兼容性更强,扩展性更强的类提供了好的解决方案。

    5属性可以以接口的形式表现。接口里不能定义数据成员,这在一定程度上限制我们的设计。请用属性来解决这个问题吧。

    6基于属性的索引。索引器是C#语法的特殊内容,而索引器正是通过属性来完成的,如果你想为你的类添加一个索引器,除了用属性你还能用什么呢?

    7最后一点,也是比较重要的。不要直接把公共成员转化成属性。

    看了上面的说明,是不是觉得应该马上把所有的数据成员都修改成属性了呢?在你修改前一定要阅读下面的内容。

    不要直接把公共成员转化成属性。它们在C#的源代码级上的语法虽然是相同的,但在IL上是不同的。即:o1.Name(属性)o1.Name(成员),虽然C#代码一样,但IL的代码是不一样的。所以,当你准备修改所有的数据成员时,必须重新编译类的代码,同时也要重新编译访问该类实例的所有相关代码。所以,在你设计时不要为了方便,想先用数据成员使用,然后在后期再修改成属性,这不是一个好主意。

    最后,不要为因为使用属性而使IL代码多了几行而担心。虽然数据成员在访问上比属性要快一点,但在实际运行时,不仅对人觉得是一样的,对机器而言感觉也像是一样的快,因为我的CPU越来越快了,完成一个函数调用太快了,跟完成一个数据访问一样的快(当然,这个函数得足够小,就跟我们的属性一样),呵呵。

    OK,关于使用属性的问题就先说这些。

     

  • 相关阅读:
    TypeScript中处理大数字(会丢失后面部分数字)
    多行字符串换行符(`) + 模板字符串
    ES6 阮一峰阅读学习
    ms转成00:00:00的时间格式化
    android侧滑效果,SlidingMenu配置
    Android Developers:按需求加载视图
    Python测试代理ip是否有效
    JavaScript去除数组中重复的数字
    Python连接redis
    [已解决]报错: Creating Server TCP listening socket 127.0.0.1:6379: bind: No error
  • 原文地址:https://www.cnblogs.com/shihao/p/1674598.html
Copyright © 2011-2022 走看看