教你写出优雅的代码(一)

来源:互联网 发布:羊毛毡小猫咪淘宝 编辑:程序博客网 时间:2024/05/17 00:18

    喜欢“雅黑”。我喜欢“优雅”、“典雅”这一些带“雅”字的形容词,貌似这样形容字的很漂亮的感觉。

    那么说一说如何写出有品位的代码,优雅的代码。

    这一点我们老师也经常强调O(∩_∩)O~

     

使用属性代替可访问的数据成员。

     

     C#将属性从其他语言中的一种特殊约定提升成为一种第一等(first-class)的语言特性。如果大家还在类型中定义公有的数据成员,请赶快停下来。属性在使我们可以将数据成员暴露为公有接口的同时,还为我们提供了在面向对象环境中所期望的封装。在C#中,属性(property)是这样一种语言元素:它们在被访问的时候看起来好像是数据成员,但是它们却是用方法实现的。      

 

    .NET框架假定我们会使用属性来表达公有数据成员。事实上,.NET框架中的数据绑定类只支持属性,而不支持公有数据成员。这些数据绑定类会将对象的属性关联到用户界面控件(Web控件或者Windows Forms控件)上。其数据绑定机制事实上是使用反射来查找一个类型中具有特定名称的属性。例如下面的代码:

textBoxCity.DataBindings.Add("Text",address, "City");便是将textBoxCity控件的Text属性和address对象的City属性绑定在一起。

       

    当然,数据绑定所应用的类一般都要和用户界面打交道。但这并不意味着属性只在UI(用户界面)逻辑中有用武之地。对于其他类和结构,我们也需要使用属性。随着时间的推移,新的需求或行为往往会影响原来类型的实现,采用属性比较容易能够应对这些变化。例如,我们可能很快就会发现Customer类型不能有一个空的Name。如果我们使用一个公用属性来实现Name,那么只需要在一个地方做更改即可。

    还有一点,大家可能没有注意到,就是属性可以实现为抽象,而抽象是面向对象的四大特征之一哦!

   

    属性在C#中已经成为一项比较完善的、第一等的语言元素。我们可以针对成员函数做的任何事情,对于属性也同样适用。毕竟,属性是对访问/修改内部数据的方法的一种扩展。

 

    我们知道,属性访问器在编译后事实上是两个分离的方法。在C# 2.0中,我们可以为一个属性的get访问器和set访问器指定不同的访问修饰符。这使得我们可以更好地控制属性的可见性。

       

 运行时常量(readonly)优于编译时常量(const

  

        C#中,我们使用readonly关键字来声明运行时常量,用const关键字来声明编译时常量。
        // 编译时常量:
        public const int _Millennium = 2000;
        //
运行时常量:
        public static readonly int _ThisYear = 2004;

       

    使用const较之于使用readonly的唯一好处就是性能:使用已知常量值的代码效率要比访问readonly值的代码效率稍好一点。但是这其中的效率提升是非常小的,大家应该和其所失去的灵活性进行一番权衡比较。在打算放弃灵活性之前,一定要对两者的性能差别做一个评测。

 

    只有当某些情况要求变量的值必须在编译时可用,才应该考虑使用const,例如:特性(attribute)类的参数,枚举定义,以及某些不随组件版本变化而改变的值。否则,对于其他任何情况,都应该优先选择readonly常量,从而获得其所具有的灵活性。

     

总是提供ToString()方法。

 

    System.Object默认提供的ToString()方法会返回类型的名称。这样的信息一般没有什么用处,像"Rect""Point""Size"这样的字符串大多都不是我们希望显示给用户的。但如果我们不重写ObjectToString()方法,用户看到的就将是这些。我们只需要写一次,但是客户将享用无数次。一点点付出,就可以让很多人(包括我们自己)受益。

    让我们来看看重写System.Object.ToString()这个最简单的需求。该方法主要的功能就是为类型提供一个最常用的文本表示。例如,考虑下面这个具有三个字段的Customer类:

public class Customer
{
    private string _name;
   
private decimal _revenue;
   
private string _contactPhone;
}

    如果不提供重写的版本,Customer将继承Object类的ToString()方法,也就是返回一个"Customer"字符串。这个字符串实在没有什么用处。即使ToString()方法只应用于调试的目的,它也应该输出一个更有意义的字符串。我们重写的时候应该尽量考虑客户所希望的表示。就Customer类来说,返回_name是一个不错的选择之一:

public override string ToString()
{
    return _name;
}

    人们总有获取类型信息的需求,而字符串对于人来说是最容易理解的。我们应该积极地去做这件事,而重写所有类型中的ToString()方法可能是所有做法中用最简单的。