最近一直在看Jeffrey的《.net框架设计 Via C#》,很好的一本讲述C#.net本质的书。推荐给所有C#以及.net平台的Programmer。看着看着偶有所得便就想拿出来写写,和大家分享。顶着南瓜大的头(最近天气变冷,近几年来首次感冒了,最大的感觉是就头变得有南瓜那么大...
...),写一写属性(Property),今天是感恩节,也算是我感恩自己可以读到这很么多前辈们写的好书,感恩自己南瓜大的脑袋还能看得懂前辈们的技术文章。
1, What is property?
此处属性(Property),指的是C#提供的一种以方便的语法访问一个方法的手段。而非另外一种属性(Attribute).下同。
属性是什么?本质上讲属性是方法,表面上看属性是字段。这样讲或许有些绕,看如下代码:
//Platform: WinXp + Visual Studio2003(C#)
using System; using System.Text; namespace Class1 { class Person { public Person(string name, int age) { _name = name; _age = age; } private string _name; private static int _age=0;
public static int Age //属性---本质是函数 (1) { get { return _age; } set {
if(value<1 || value>100) throw new ArgumentOutOfRangeException("value","人能活到100岁以上,请思考一下."); else _age = value; } } public string this[int n] //有参属性 { get { StringBuilder sb = new StringBuilder(); for(int i=0; i<n;i++) { sb.Append(_name); } return sb.ToString(); } set { _name = value; } } } class ExcelProgram { [STAThread] static void Main(string[] args) { Console.WriteLine(Person.Age); //属性--用起来像字段 (2) Person per = new Person("Jerry",25); Console.WriteLine(per[4]+ " "+Person.Age); (3)
Console.ReadLine(); } } }
|
这里我定义了一个很简单的类Person,该类有两个字段(fileds),分别是_name和_age代表着一个人的"姓名"和"年龄".代码中的(1)处(以红色字标出),我定义了一个属性Age。而在(2),(3)处,我分别使用了属性和有参属性(待会讲述)。
2,How can we use property in C#?
1st,Define a property.
在C#中,定义一个属性很简单:
public int Age
{
set{};
get{};
}
其中public指出了该属性的可访问性;int指出了属性的返回类型;Age是属性名。其中的get和set是两个方法分别用来设置(set)和获取属性(get)。
对于CLR/CLS来讲并没有属性(Property)这个概念,属性(Property)这个概念是虚拟出来的,是为了使用的方便,上面的代码,等同于下面这样定义的方法(记住了--属性的本质是方法):
public int set_Age()
{}
public int get_Age(int value)
{}
在属性中,你甚至可以分别为set和get定义不同的可访问性,像这样:
public int Age
{
protected set{};
get{};
}
2nd,Use a property.
使用属性比定义属性还简单。属性的使用和字段使用方法是一样的,例如你可以这样用字段(在上例中若定义一个无参构造(default ctor)并将字段(fields)的访问性设为public即可):
Person perJerry = new perJerry{)
perJerry._name = "Jerry";
perJerry._age = 25;
属性允许你也同样的语法来实现:
Person perJerry = new perJerry{)
perJerry.Name = "Jerry";
perJerry.Age = 25;
3rd. Essential of property.
属性(Property)的本质是方法,口说无评,我们来看看刚才上面的一段程序,对于CLR来看是什么样子的。我们利用ILDasm来反汇编刚来的那段程序,如下图
图上红色的三角形,标着pro Age说明Age是一个属性(Property),其实这部分是属性的元数据,为什么这样讲呢,我们双击打开pro Age可以看到如下内容
该部分只有方法的定义,并没有实现部分,那么属性的实现部分在哪里呢?你可能会注意到了,真正实际get的方法是get_Age().第一幅图中红色三角形上面的四个method实际上实现了属性(的操作).让我们再双击method set_Age看看
可以看出set_Age方法,实现了Age属性中的set操作.为了再次验证属性的本质是方法,我们在Person类中再添加一个方法get_Age(),形如:
public int get_Age()
{
return _age;
}
当试图编译代码时,会出现以下错误信息:
类“Class1.Person”已经定义了一个具有相同参数类型的名为“get_Age”的成员
既然属性(property)的本质是方法(method),这下就简单了。下面这些属性的特性也理所当然了:
1,你可以定义静态(static)属性,上例中我便给出了static属性;
2,你可以分别定义set,get。也可以只定义一个set(只写属性)或是只定义一个get(只读属性);
3,你可以分别为set,get设定访问类型--就像你可以分别是set_Age method和get_Age method分别设定访问类型一样;
4,属性也可以有参数;
3rd, property with parameter.
你也许会问第一幅图中的get_Item和set_Item是什么,这便是有参属性。有参属性也称作索引器(Indexer).有参属性只能像下面这样定义(利用参数检索一个类(或实例)的相关信息)
public string this[int n]
{
get
{
StringBuilder sb = new StringBuilder();
for(int i=0; i {
sb.Append(_name);
}
return sb.ToString();
}
}
当编译器看到这样的定义时,会自动添加一个属性pro Item,并用set_Item,get_Item两个method来实现该属性。之后我们便可以像这样的使用属性:
Person per = new Person("Jerry",25);
Console.WriteLine(per[4]);
4th, Something you must notice.
一般在编译过程中若生成release版本(打开release选项),属性会被内联。而在Debug版本则不会被内联系,因为如果内联代码的话,很难单步执行调试.
属性并不是CLR/CLS支持的,因此并不是所有.net语言都支持属性。当你所使用的语言不支持属性时,你完全可以定义方法来实现相应的功能。
Jerry.Chow
11/22'07
阅读(1485) | 评论(0) | 转发(0) |