随着VS2010的发布,C#的版本也升级到4.0,相对于2.0,增加了很多新特性,为我们的开发带来了很大的便利,通过这些特性,使我们编码的效率更高,代码更加易读、简洁。很遗憾,我们的都还停留在2.0的编码环境中,不过我的观点,既然这些特性能给我们带来便利,就值得学习,即使现在不用,将来也会用到!
最近我会写几篇文章逐个介绍C#3.0以后各个版本中增加的新特性,今天为大家带来的是一个简单的特性:Automatically Implemented Property
首先大家回忆一下,C#中如何定义一个简单的类,首先定义类需要的字段,再定义对外的属性,再提供一个构造函数……
public class Boy { private string name; private int age; public string Name { get { return name; } set { name = value; } } public int Age { get { return age; } set { age = value; } } public Boy(string n, int a) { this.name = n; this.age = a; } }
特别是当某对象属性非常多的时候,相当麻烦,VS2005以后提供了在重构中增加了封装字段功能,可以帮助开发人员快速根据字段生成属性,但仍然很麻烦。
那时候我们项目组还专门开发了一个代码生成器,根据定义好的字段批量生成属性,在根据业务对个别属性的可见性进行调整。
下面我在用Automatically Implemented Property特性来编写一个类
public class Girl { public string Name { get; set; } public int Age { get; set; } public Girl(string n, int a) { this.Name = n; this.Age = a; } }
从这个例子里我们可以很直观的看到新特性带来的便利,省去了和属性对应的字段定义,在get/set中我们只需要一个申明式的语句,而不需要去实现它(Automatically Implemented),它将我们从很多复杂的工作中解放出来。而且代码看起来更加整洁。
可能大家关心这种定义方式在底层有什么不同,其实3.0的编译器只是帮我加了一些代码,节省了我们的很多工作,最后两者生成的代码是完全一样的,
我可以用Reflector看一下最终编译的程序集
通过对比大家发现Boy中就是我们定义的两个字段和属性,而在Girl中我们没有定义字段,但编译器自动帮我们生成了两个名为“<属性名>k_BackingField”的字段,它们在程序中的作用就相当于Boy中用户自己定义的两个字段的作用,大家可以把Girl反编译一下看看,最终生成的代码,和2.0定义的方式一样。
当然这种定义方式也有一个弊端,就是原来我们可以在属性中进行的校验现在没法胜任了,比如:
private int age; public int Age { get { return age; } set { if (value > 0 && value < 150){ age = value; } else{ throw new ArgumentOutOfRangeException("Error"); } } }
个别属性个别处理,而且这种校验也可以通过其他方法绕过,比如写在构造函数中。
这个特性还是非常酷的,大家有兴趣的可以试试!