索引器允许类或结构的实例按照与数组相同的方式进行索引。索引器类似于属性,不同的是它们的访问器采用参数。
【为什么使用索引器】
    我们现在需要描述一个班级,当然这个班级具有多个学生,我们首先抽象出学生类如下:

class Student
 {
  private int _age;
  public int Age
  {
   get
   {
    return _age;
   }
   set
   {
    _age++;
   }
  }
  public Student(int i)
  {
   _age = i;
  }
  public void Study()
  {
   Console.WriteLine("好好学习,天天向上" + _age.ToString());
  }
 }

抽象出的班级类如下:

class As2t004Class
 {
  Student[] studensts = new Student[20];
  static void Main(string[] args)
  {
   As2t004Class ac =new As2t004Class();
   Student s;
   for( int i = 0;i<ac.studensts.Length;i++)
   {
    s = new Student(i);
    ac.studensts[i] = s;
   }
   s = new Student(250);
   s = ac[s];
   if( s==null )
   {

   }
   else
   {
    s.Study();
   }
   s = new Student(18);
   s = ac[s];
   if( s==null )
   {

   }
   else
   {
    s.Study();
   }
   
  }
  public Student this[ Student ss]
  {
   get
   {
    foreach( Student s in studensts )
    {
     if( ss.Age == s.Age )
     {
      Console.WriteLine("存在此人!");
      return s;
     }
     else
     {
      
     }
    }
    Console.WriteLine("走错门了");
    return null;
   }
  }
  public Student this[int index]
  {
   get
   {
    if(( index <0 )||(index >=studensts.Length))
    {
     Console.WriteLine("Error");
     return null;
    }
    else
    {
     return studensts[index];
    }
   }
   set
   {
    if(( index <0 )||(index >=studensts.Length))
    {
     Console.WriteLine("Error");
    }
    else
    {
      studensts[index] = value;
    }

   }
  }
 }


class As2t004Class
 {
//在班级类中声明一个数据类型为Student类的数组,相当于班级中的座位,每个座位坐一名学生;
  Student[] studensts = new Student[20];
  static void Main(string[] args)
  {
   As2t004Class ac =new As2t004Class();
   Student s;
   for( int i = 0;i<ac.studensts.Length;i++)
   {
//新来一名学生;
    s = new Student(i);
//把学生安排到座位上;

    ac.studensts[i] = s;
//大家看,现在的问题来了,虽然通过   ac.studensts[i] = s;这段代码可以实现,但是太麻烦了,能不能安照数组
//的使用方法来访问   ac.studensts这个数组呢?
   }
   s = new Student(250);
   s = ac[s];
   if( s==null )
   {

   }
   else
   {
    s.Study();
   }
   s = new Student(18);
   s = ac[s];
   if( s==null )
   {

   }
   else
   {
    s.Study();
   }
   
  }
  public Student this[ Student ss]
  {
   get
   {
    foreach( Student s in studensts )
    {
     if( ss.Age == s.Age )
     {
      Console.WriteLine("存在此人!");
      return s;
     }
     else
     {
      
     }
    }
    Console.WriteLine("走错门了");
    return null;
   }
  }
  public Student this[int index]
  {
   get
   {
    if(( index <0 )||(index >=studensts.Length))
    {
     Console.WriteLine("Error");
     return null;
    }
    else
    {
     return studensts[index];
    }
   }
   set
   {
    if(( index <0 )||(index >=studensts.Length))
    {
     Console.WriteLine("Error");
    }
    else
    {
      studensts[index] = value;
    }

   }
  }
 }

【使用索引器】

public Student this[ Student ss]
  //声明一个索引器,返回类型是Student,this关键字的作用指向对象自己,【】指明索引器类型,如果形参类型是Student,那么就调用本索引器。当然返回的对象没有必要是studensts
  {
   get
   {
    foreach( Student s in studensts )
    {
     if( ss.Age == s.Age )
     {
      Console.WriteLine("存在此人!");
      return s;//也可以更换为 return new Student(500);
     }
     else
     {      
     }
    }
    //return 关键字的作用不但可以结束循环,还可以结束整个方法
    //所以,如果没有执行(71),那么就是没有找到改名同学
    Console.WriteLine("走错门了");
    return null;
   }
  }
  public int this[int index]
  {
   get
   {
    return 0;
   }
  }
  public Student this[int index]
  {
   get
   {
    if(( index <0 )||(index >=studensts.Length))
    {
     Console.WriteLine("Error");
     return null;
    }
    else
    {
     return studensts[index];
    }
   }
   set
   {
    if(( index <0 )||(index >=studensts.Length))
    {
     Console.WriteLine("Error");
    }
    else
    {
      studensts[index] = value;
    }

   }
  }
 }
}

 

【索引器与方法重载】

       C#语言中,如果同一个类中的方法名相同,但是参数列表不同,我们称这种现象为方法的重载。现在我们声明两个索引器如下:

       public Student this[int index]

   public Student this[Student student]

由于以上两个方法的方法名是相同的“this”,但是他们的参数类表不同,所以上述两个方法可以共存。好了,我们再添加一个方法:

   public int this[Student student]

      {

        get

        {

           int i =0;

           foreach( Student s in stundts )

           {

              if(s.name == student.name)

              {

              i++;

              }

           }

           return i;

       

        }

      }

上述方法没有任何语法错误,它的作用是统计与student同名的对象个数,然而,由于它的参数类表与原有方法相同,因此是不允许的。

总之,在一个类内部不允许存在两个参数列表相同的索引器。


 


 

posted on 2007-09-26 16:53  段静迪  阅读(361)  评论(1编辑  收藏  举报