C#属性简写的原理分析

在C#里面,我们为一个private字段对外暴露Property达到数据保护封装的目的。估计大家都有过对于大数据量的类添加Property的枯燥经历;或者 private字段和Property之一名称发生改变,没有调整对应项名称,可能在以后长期开发和维护中,带来不易察觉的错误。在其实C#允许我们用一种简便的属性写法,来定义和操作一个类的字段。如下面代码中的CarName002。

public class Car
{
private string carName001;

public string CarName001
{
get
{
return this.carName001;
}
set
{
this.carName001 = value;
}
}

public string CarName002
{
get;
set;
}
}

 

属性简写内部实现

对于实现,估计很多人都知道,这个是CLR在内部生成了辅助的字段,我们具体验证一下,我们看看上面例子的IL代码:

我看可以看到,一个名为<CarName002>k_BackingField的字段,这个是我们没有定义的。双击得到更详细的信息:

这样就明确了,这个是一个私有实例字段,System.Runtime.CompilerServices.CompilerGeneratedAttribute说明这个是由编译器生成的。

 

后续问题分析1

 这个简写属性和内部的同名字段有对应关系吗?这个还是个比较普遍的疑问,从IL code来看,他们对应的是不同的字段,是没有对应关系的。口说无凭,我们具体测试一下:

定义了同名(首字母大小写不通)的字段:
public class Car
{
private string carName001;
private string carName002;

public string CarName001
{
get
{
return this.carName001;
}
set
{
this.carName001 = value;
}
}

public string CarName002
{
get;
set;
}

public string GetCarName002()
{
return this.carName002;
}
}

在Main方法中:
Car car1 = new Car();
car1.CarName002 = "002";
System.Console.WriteLine("private carName002 value is " + car1.GetCarName002());
System.Console.ReadLine();

 

后续问题分析2

如果我需要一个属性对外只读,对类自身而言可以对其值进行修改怎么做?分别定义get和set的修饰符即可。

        public string CarName002
{
get;
private set;
}

 

总结,属性简写带来了很多便捷,但是需要注意:
1. 要从具体的需要出发,比如属性简写不能加入复杂的逻辑。
2. 要从使用习惯和具体的项目风格出发,要照顾到自己的和他人的编码习惯,以及项目的代码风格的一致性。

posted @ 2011-12-22 14:25  K.W  Views(11292)  Comments(5Edit  收藏  举报