Indexer

索引的声明包括:可选的访问修饰符,返回值的类型,关键字this(不能省略),
和函数参数类似的参数(不过是方括号,而不是函数的圆括号),然后是索引体。
你不能使用静态索引,所以你不能在索引的声明中使用static关键字。
索引可以被声明为虚拟的,因此它可以在它的派生类中被重载。
索引的参数不能使用ref/out型参数。例如:
1   struct  StringSection
2 {
3public char this [ref int at]//错误
4 
5}

注意,这里的属性名是this,意思是回引类的当前实例,参数列表包含在方括号而非括号之内。

索引的声明和属性一样:只能含有set/get语句。
    当使用一个索引表达式进行读操作时,索引的get语句自动运行
    当使用一个索引表达式进行写操作时,索引的set语句自动运行

属性和索引器

属性和索引器之间有好些差别:

类的每一个属性都必须拥有唯一的名称,而类里定义的每一个索引器都必须拥有唯一的签名(signature)或者参数列表(这样就可以实现索引器重载)。

属性可以是static(静态的)而索引器则必须是实例成员。

为索引器定义的访问函数可以访问传递给索引器的参数,而属性访问函数则没有参数

接口与索引

接口定义索引器,如IList和 IDictionary集合接口都声明了索引器以便访问其存储的项目。

在为接口声明索引器的时候,记住声明只是表示索引器的存在。你只需要提供恰当的访问函数即可,不必包括范围修饰符。只需定义作因名称,相应的实现方法则应该为该类提供该类的索引器的方法.以下代码把索引器声明为接口IImplement的一部分:


下面附上一个例子
using  System;
using  System.Collections;
// using System.Collections.Generic;
using  System.Text;
namespace  ConsoleApplication1
{
    
class Indexer
    
{
        
static void Main(string[] args)
        
{
            test t 
= new test();
            
// 初始取值
            Console.WriteLine(t[0]);
            Console.WriteLine(t[
1]);
            Console.WriteLine(t[
2]);

            
// 重新赋值
            t[0= "zhoumin";
            t[
1= "welcome";
            Console.WriteLine(t[
0]);
            Console.WriteLine(t[
1]);
            Console.WriteLine(t[
2]);

            Console.WriteLine(
"**************************************************");

            t[
"first"= "第一个";
            t[
"second"= "第2个";
            t[
"third"= "第3个";

            
// 注意:此处以string类型作为输入参数的Indexer被重新赋值
            t["a"= "ha,ha";
            Console.WriteLine(t[
"first"]);
            Console.WriteLine(t[
"second"]);
            Console.WriteLine(t[
"third"]);
            Console.WriteLine(t[
"what"]);

            Console.ReadLine();
        }

    }

    
class test
    
{
        
// 定义私有域 外部不能访问 string数组
        private string[] names;
        
public test()
        
{
            names 
= new string[3];
            names[
0= "abc";
            names[
1= "xyz";
            names[
2= "911";
        }

        
public string this[int index]
        
{
            
get
            
{
                
return this.names[index];
            }

            
set
            
{
                
this.names[index] = value;
            }

        }

         
public string this[string n]
//        public object this[string n]
        {
             
/*如你你所看到的那样,属性声明倒更像是域声明,只不过它还声明了两个特殊的成员,
             按照微软的说法就是所谓的访问函数(accessor)。当某一表达式的右边调用属性或者属性用作其他子程序(或者函数)的参数时即会调用get访问函数。
             反之,当表达式左边调用属性并且通过隐式传递value参数设置私有域值的情况下就会调用set访问函数。
             你可以创建只读属性,方法是省略set访问函数,这样任何设置属性的尝试都会产生编译错误。
*/
 

            
get 
            
{
                
if ((string)n == "first"return names[0];
                
if ((string)n == "second"return names[1];
                
if ((string)n == "third"return names[2];
                
return "null";
            }

            
set
            
{
                
if (n == "first") names[0= (string)value;
                
else if (n == "second") names[1= (string)value;
                
else if (n == "third") names[2= (string)value;
                
else names[0= names[1= names[2= (string)value;
                
            }

        }

    }

}

输出:
abc
xyz
911
zhoumin
welcome
911
****************************************
ha,ha
ha,ha
ha,ha
null

你可能感兴趣的:(index)