和函数参数类似的参数(不过是方括号,而不是函数的圆括号),然后是索引体。
你不能使用静态索引,所以你不能在索引的声明中使用static关键字。
索引可以被声明为虚拟的,因此它可以在它的派生类中被重载。
索引的参数不能使用ref/out型参数。例如:
1
struct
StringSection
2 {
3public char this [ref int at]//错误
4
5}
2 {
3public char this [ref int at]//错误
4
5}
注意,这里的属性名是this,意思是回引类的当前实例,参数列表包含在方括号而非括号之内。
索引的声明和属性一样:只能含有set/get语句。
当使用一个索引表达式进行读操作时,索引的get语句自动运行
当使用一个索引表达式进行写操作时,索引的set语句自动运行
属性和索引器
属性和索引器之间有好些差别:
类的每一个属性都必须拥有唯一的名称,而类里定义的每一个索引器都必须拥有唯一的签名(signature)或者参数列表(这样就可以实现索引器重载)。
属性可以是static(静态的)而索引器则必须是实例成员。
为索引器定义的访问函数可以访问传递给索引器的参数,而属性访问函数则没有参数
接口与索引
接口定义索引器,如IList和 IDictionary集合接口都声明了索引器以便访问其存储的项目。
在为接口声明索引器的时候,记住声明只是表示索引器的存在。你只需要提供恰当的访问函数即可,不必包括范围修饰符。只需定义作因名称,相应的实现方法则应该为该类提供该类的索引器的方法.以下代码把索引器声明为接口IImplement的一部分:
1interface IImplement {
2
3string this[int index]
4{
5get;
6set;
7}
8}
下面附上一个例子
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;
}
}
}
}
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