| 添加到收藏夹 | 返回目录页 | 上一篇:C#锐利体验(7.1) |
C#锐利体验(8.1)
索引器索引器(Indexer)是C#引入的一个新型的类成员,它使得对象可以像数组那样被方便,直观的引用。索引器非常类似于我们前面讲到的属性,但索引器可以有参数列表,且只能作用在实例对象上,而不能在类上直接作用。下面是典型的索引器的设计,我们在这里忽略了具体的实现。
class MyClass
{
public object this [int index]
{
get
{
// 取数据
}
set
{
// 存数据
}
}
}
索引器没有像属性和方法那样的名字,关键字this清楚地表达了索引器引用对象的特征。和属性一样,value关键字在set后的语句块里有参数传递意义。实际上从编译后的IL中间语言代码来看,上面这个索引器被实现为:
class MyClass
{
public object get_Item(int index)
{
// 取数据
}
public void set_Item(int index, object value)
{
//存数据
}
}
由于我们的索引器在背后被编译成get_Item(int index)和set_Item(int index, object value)两个方法,我们甚至不能再在声明实现索引器的类里面声明实现这两个方法,编译器会对这样的行为报错。这样隐含实现的方法同样可以被我们进行调用,继承等操作,和我们自己实现的方法别无二致。通晓C#语言底层的编译实现为我们下面理解C#索引器的行为提供了一个很好的基础。
和方法一样,索引器有5种存取保护级别,和4种继承行为修饰,以及外部索引器。这些行为同方法没有任何差别,这里不再赘述。唯一不同的是索引器不能为静态(static),这在对象引用的语义下很容易理解。值得注意的是在覆盖(override)实现索引器时,应该用base[E]来存取父类的索引器。
和属性的实现一样,索引器的数据类型同时为get语句块的返回类型和set语句块中value关键字的类型。
索引器的参数列表也是值得注意的地方。“索引”的特征使得索引器必须具备至少一个参数,该参数位于this关键字之后的中括号内。索引器的参数也只能是传值类型,不可以有ref(引用)和out(输出)修饰。参数的数据类型可以是C#中的任何数据类型。C#根据不同的参数签名来进行索引器的多态辨析。中括号内的所有参数在get和set下都可以引用,而value关键字只能在set下作为传递参数。
下面是一个索引器的具体的应用例子,它对我们理解索引器的设计和应用很有帮助。
using System;
class BitArray
{
int[] bits;
int length;
public BitArray(int length)
{
if (length < 0)
throw new ArgumentException();
bits = new int[((length - 1) >> 5) + 1];
this.length = length;
}
public int Length
{
get { return length; }
}
public bool this[int index]
{
get
{
if (index < 0 || index >= length)
throw new IndexOutOfRangeException();
else
return (bits[index >> 5] & 1 << index) != 0;
}
set
{
if (index < 0 || index >= length)
throw new IndexOutOfRangeException();
else if(value)
bits[index >> 5] |= 1 << index;
else
bits[index >> 5] &= ~(1 << index);
}
}
}
class Test
{
static void Main()
{
BitArray Bits=new BitArray(10);
for(int i=0;i<10;i++)
Bits[i]=(i%2)==0;
Console.Write(Bits[i]+" ");
}
}
编译并运行程序可以得到下面的输出:
True False True False True False True False True False
上面的程序通过索引器的使用为用户提供了一个界面友好的bool数组,同时又大大降低了程序的存储空间代价。索引器通常用于对象容器中为其内的对象提供友好的存取界面--这也是为什么C#将方法包装成索引器的原因所在。实际上,我们可以看到索引器在.NET Framework类库中有大量的应用。
↓相关文章:
- · 数据结构与算法(C#实现)系列---树(三)
- · Snake.Net中的ORM(二)
- · Autodesk官方最新的.NET教程(一)(C#版)
- · C#冒泡算法!
- · ReferenceEquals, == , Equals 比较
- · C#2.0新特性探究之模拟泛型和内置算法
- · 如何保持datarow是DataRowState.Added
- · O/R Mapping 研究报告(1)
- · nhibernate架构分析(uml图)
- · C# 特性(Attribute)入门(一)
- · .NET断想
- · 基于C#的接口基础教程之五(6)
- · 基于C#的接口基础教程之五(4)
- · 基于C#的接口基础教程之五(2)
- · 基于C#的接口基础教程之三
- · 到底什么是 O/R Mapper
- · Visual C#托管Socket的实现方法(一) (3)
- · 保护你的代码——谁动了我的组件?
- · 用Visual C#实现文件下载功能(1)
- · 通过.NET Framework访问活动目录(2)
- · 轻松访问系统资源
- · C#锐利体验(8.1)
- · C#锐利体验(6.4)
- · C#锐利体验(6.1)
- · Visual C#中使用线程(3)
- · 从Windows DNA到.NET(3)
- · 从Windows DNA到.NET(1)
- · 微软公布“.NET”第二阶段研发方向
- · C#网络编程初探(3)
- · .NETFramework发现漏洞 可能导致信息丢失
- · 使用.NET Framework 进行事务处理
- · Visual C#.Net网络程序开发-Tcp篇(3)
- · 简化.NET装配库
- · .NET编译技术内幕
- · 浅析C#中的套接字编程(5)
- · 浅析C#中的套接字编程(1)
- · 使用C#轻松编写.Net组件(1)
- · 使用C#开发一个简单的P2P应用
- · Visual Studio.Net 内幕(8)
- · Visual Studio.Net 内幕(6)
- · Visual Studio.Net 内幕(4)
- · Visual Studio.Net 内幕(2)
- · Visual Studio.NET Tips 1-5
- · C#锐利体验(5.2)
- · C#锐利体验(2.2)

