Chinaunix首页 | 论坛 | 博客
  • 博客访问: 570117
  • 博文数量: 155
  • 博客积分: 4015
  • 博客等级: 上校
  • 技术积分: 1625
  • 用 户 组: 普通用户
  • 注册时间: 2005-11-18 16:55
文章分类

全部博文(155)

文章存档

2009年(20)

2008年(39)

2007年(66)

2006年(29)

2005年(1)

我的朋友

分类:

2007-11-22 14:03:36

  最近一直在看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) |
0

上一篇:走路 or 散步

下一篇:外出吃饭

给主人留下些什么吧!~~