8.1 属性

视频讲解:光盘\TM\lx\8\01属性.mp4

属性提供功能强大的方法以将声明信息与C#代码(类型、方法、属性等)相关联,一旦属性与程序实体关联,即可使用名为反射的技术对属性进行查询。本节将对属性进行详细讲解。

8.1.1 属性概述

属性是一种用于访问对象或类的特性的成员,它可以表示字体的大小、窗体的标题和客户的名称等内容。

属性有访问器,这些访问器指定在它们的值被读取或写入时需要执行的语句。因此属性提供了一种机制,它把读取和写入对象的某些特性与一些操作关联起来。可以像使用公共数据成员一样使用属性,但实际上它们是称为“访问器”的一种特殊方法,这使得数据在被轻松访问的同时,仍能提供方法的安全性和灵活性。

对于属性的理解其实并不难,相信大家都玩过游戏吧,其实在游戏中也能找到属性,例如人物属性,常见的有攻击、防御、速度、智力、敏捷、力量、生命值、魔法值等;而物品属性是用来加强人物属性的,常见的有加攻击力、加防御力、加生命、加魔法、加抗性等。

注意 属性不能作为ref参数或out参数传递。

属性具有以下特点:

属性可向程序中添加元数据。元数据是嵌入程序中的信息,如编译器指令或数据描述。

程序可以使用反射检查自己的元数据。

通常使用属性与COM交互。

属性以两种形式存在:一种是在公共语言运行库的基类库中定义的属性,另一种是自己创建、可以向代码中添加附加信息的自定义属性。

【例8.1】下面代码用来将System.Reflection.TypeAttributes.Serializable属性用于自定义类,以便使该类中的成员可以序列化,代码如下。

        [System.Serializable]
        public class MyClass
        {}

上面代码中的Serialzable为.NET Framework类库中定义的属性。

自定义属性在类中是通过以下方式声明的:指定属性的访问级别,后面是属性的类型,接下来是属性的名称,然后是声明get访问器和(或)set访问器的代码模块,其他语法格式如下:

        访问修饰符 数据类型 属性名
        {
            get
            {
              return变量名;
            }
            set
            {
              变量名 =vaIue;
            }
        }

访问修饰符用来确定属性的可用范围,下面介绍常用的几个访问修饰符。

public:不限制对该属性的访问。

protected:只能从其所在类和所在类的子类(派生类)进行访问。

internal:只有其所在类才能访问。

private:私有访问修饰符,只能在其声明类中使用。

【例8.2】下面代码自定义了一个Date类,该类中有一个属性day,因为该属性提供了get和set访问器,因此它是可读可写属性,代码如下。

        public class Date
        {
            private int Day = 7;
            public int day                   //星期属性,该属性为可读可写
            {
              get{returnDay; }
              set
              {
                  if ((value > 0) && (value < 8))
                  {
                      Day=vaIue;
                  }
              }
            }
        }

说明 get访问器与方法体相似,它必须返回属性类型的值;而set访问器类似于返回类型为void的方法,它使用称为value的隐式参数,此参数的类型是属性的类型。

8.1.2 属性的使用

程序中调用属性的语法格式如下。

对象名.属性名

注意 ① 如果要在其他类中调用自定义属性,必须将自定义属性的访问级别设置为public。

② 如果属性为只读属性,不能在调用时为其赋值,否则产生异常。

【例8.3】创建一个控制台应用程序,其中定义了一个MyClass类,并在该类中定义了两个string类型的变量,分别用来记录用户的编号和姓名,然后在该类中自定义两个属性,用来表示用户编号和姓名。定义完成后,在Program主程序类中实例化自定义类MyClass的一个对象,并分别对其中定义的用户编号和用户姓名属性赋值,最后调用Console类的WriteLine方法将赋值后的用户编号和用户姓名输出。程序代码如下。(实例位置:光盘\TM\sl\8\1)

        class MyClass
        {
            private string id="";             //定义一个string类型的变量,用来记录用户编号
            private string name="";           //定义一个string类型的变量,用来记录用户姓名
            public string ID                  //定义用户编号属性,该属性为可读可写属性
            {
              get
              {
                  returnid;
              }
              set
              {
                  id=vaIue;
              }
            }
            public string Name                //定义用户姓名属性,该属性为可读可写属性
            {
              get
              {
                  returnname;
              }
              set
              {
                  name=vaIue;
              }
            }
        }
        class Program
        {
            static void Main(string[] args)
            {
              MyClass myclass=new MyClass();                      //实例化MyClass类对象
              mycIass.ID="BH001";                                 //为用户编号属性赋值
              mycIass.Name="TM1";                                 //为用户姓名属性赋值
              Console.WriteLine(myclass.ID+" "+myclass.Name);     //输出用户编号和用户姓名
              mycIass.ID="BH002";                                 //重新为用户编号属性赋值
              mycIass.Name="TM2";                                 //重新为用户姓名属性赋值
              Console.WriteLine(myclass.ID+" "+myclass.Name);     //再次输出用户编号和用户姓名
          }
        }

按Ctrl+F5键查看运行结果,如图8.1所示。

图8.1 属性的使用实例运行结果