属性、索引器知识点和练习

知识点

一、属性(Property)为我们提供了一种控制类中字段访问的简捷方法
1、什么是属性
属性(Property)是逻辑字段和物理方法的一个交集。属性的用法和字段完全相同,从逻辑上说属性就是一个字段。不过,编译器会将这个字段风格的语法自动转换为对特殊的accessor方法的调用。

1)属性的声明:
属性访问修饰符 属性类型 属性名
{
  get //取值代码或称get accessor
  {
    ...
  }
  set //赋值代码或称set accessor
  {
    ...
  }
}

 

2)使用属性
属性的好处:简言之,在访问对象成员时,既维持了封装性(即如果成员是私有时,通过对象名.成员名还是无法直接访问成员),又可以使用简洁的字段风格语法(即,虽然成员字段还保持私有,但通过对象名.属性名可以直接访问该成员字段,且书写非常简洁)。

代码中要注意:
a、成员变量字段要以小写字母开头,属性名要以大写字母开头。
b、所有的set accessor都使用value这个隐藏参数来传递要写入的数据。
c、类中和结构中的属性语法是相同的。
d、set accessor在对象初始化前是不能使用的,也就是说涉及set的相关操作必须等到对象初始化后才可以进行。而成员字段是没有此限制的。
e、不能将属性作为ref或out参数来使用。(这里不懂,存留疑问)
f、在一个属性中,最多只能包含一个get accessor和一个set accessor。属性内不能包含其他的方法、字段和属性。
g、get accessor和set accessor不能获取任何参数,赋值时,使用value变量自动传递给set accessor。

 

3)只读属性和只写属性
定义属性时,同时包含get accessor和set accessor的属性称为可读写属性;只包含get accessor的属性称为只读属性;只包含set accessor的属性称为只写属性。

 

4)属性的可访问性是指属性为private、protected、public、internal。
在声明了属性的可访问性后,还可继续对其中的set和get两种访问器设置不同的可访问性。但要注意的是:两个访问器声明时的访问修饰符不能大于或等于属性的访问修饰符,如:属性声明为private,get和set两个访问器都不能再声明为private、protected和public。同时,属性的两个访问器不允许同时声明访问修饰符(即“不能为属性或索引器的两个访问器同时指定可访问性修饰符”)如果属性的访问修饰符为public,两个访问器的访问修饰符只能设置在一个属性上,只能设置为internal或private或protected我的理解:当属性的访问修饰符确定后,如果不设置访问器的访问修饰符,即默认访问器和属性同样的访问修饰符。

 

二、索引器

如果将属性视为一种智能字段的话,索引器(indexer)可视为一种智能数组。使用索引器时所用的语法与使用数组时所用的语法完全相同。

什么是索引器
索引器(indexer)是类中相当特殊的一种成员。其功能类似于数组,提供类对象索引编号,并利用索引值存取类的数组成员。索引器和数组最大的不同在于索引器提供一对存取单元,让程序员能够控制经过索引存取数组成员的操作。
索引器定义:
访问修饰符      返回对象类型 关键字this [索引值的类型 索引值变量]
AccessModifier  Type         this       [Type         argindex]
{
  get{...}
  set{...}
}

索引器中内部分别定义了get和set存取单元,get用于取得其中元素的值,而set用于设置元素的值

索引器需注意:
1)索引器不是方法,所以参数不带圆括号,但有方括号
2)索引器总是获取单个参数,该参数是在一对方括号中提供的,用于指定要访问对象的哪一个元素。
3)和属性一样,索引器包含get和set两个访问器
4)所有索引器都使用this关键字来表示命名索引器。class和struct只允许定义一个索引器,而是总是命名为this。
5)索引器和属性相似之处:它们都使用get accessor和set accessor。区别在于:属性可以声明为static,而索引器不可。
6)索引器和数组虽然相似,但也有重要区别:a、索引器可以使用非数值下标,而数组只能用整数做下标。b、索引器可以重载,与方法相似,但数组不可。c、索引器不可以作为
ref和out参数使用,这与属性相似,而数组可以。(此处存留疑问!)

 

练习

属性

using System;
using System.Collections.Generic;
using System.Text;

namespace Property
{
    class ShowString
    {
        string str1;
        string str2;
        public string Str1
        {
            get
            {
                return this.str1;
            }
            set
            {
                this.str1 = value;
            }
        }
        public string Str2
        {
            internal get//可以声明为private、protected、internal,不能再声明成public
            {
                return this.str2;
            }
            set
            {
                this.str2 = value;
            }
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            ShowString showStr1 = new ShowString();
            showStr1.Str1 = "Hello today and tomorrow!";
            Console.WriteLine(showStr1.Str1);
            Console.ReadLine();
            ShowString showStr2 = new ShowString();
            showStr2.Str2 = "Test";
            Console.WriteLine(showStr2.Str2);
            Console.ReadLine();
        }
    }
}

 

索引器

 

using System;
using System.Collections.Generic;
using System.Text;

namespace indexer
{
    class Int_Bits
    {
        static int bits;
        public static int Bits//设置为static后,下面就不能用this关键字了,因为静态不是由对象访问的,同时,get和set所访问的成员变量也必须是静态的了
        {
            get
            {
                //return this.bits;//这是错的
                return bits;
            }
            private set
            {
                bits = value;
            }
        }
        public Int_Bits(int initialValue)
        {
            //bits = initialValue;
            Int_Bits.Bits = initialValue;
        }
        public string this[string index]//索引器重载
        {
            get
            {
                return index;
            }
            
        }
        public bool this[int index]
        {
            get
            {
                return ((bits & (1 << index))!=0);//操作符的优先级,所以括号得这样打
            }
            set
            {
                if (value)
                    bits |= (1 << index);
                else
                    bits&=(~(1 << index));
            }
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            int intVar = 12;
            Console.WriteLine("测试数据为{0}",intVar);
            Int_Bits intBits1 = new Int_Bits(intVar);
            //Int_Bits.Bits = 12;
            bool bit=intBits1[2];
            Console.WriteLine("intBits1对象索引位置2处的比特为 {0}",bit);
            intBits1[3] = false;
            Console.WriteLine("intBits1对象索引位置3处的值改为0后的结果为 {0}",Int_Bits.Bits);
            Console.ReadLine();
            Console.WriteLine(intBits1["hello world!"]);
            Console.ReadLine();
        }
    }
}
posted on 2009-10-05 22:14  友闻语上  阅读(300)  评论(0编辑  收藏  举报