概述

索引器允许类或结构的实例就像数组一样进行索引。 索引器类似于属性,不同之处在于它们的访问器采用参数。

在下面的示例中,定义了一个泛型类,并为其提供了简单的 get 和 set 访问器方法(作为分配和检索值的方法)。 Program 类为存储字符串创建了此类的一个实例。

Code
复制代码
 1 class SampleCollection<T>
2 {
3 // Declare an array to store the data elements.
4 private T[] arr = new T[100];
5
6 // Define the indexer, which will allow client code
7 // to use [] notation on the class instance itself.
8 // (See line 2 of code in Main below.)
9 public T this[int i]
10 {
11 get
12 {
13 // This indexer is very simple, and just returns or sets
14 // the corresponding element from the internal array.
15 return arr[i];
16 }
17 set
18 {
19 arr[i] = value;
20 }
21 }
22 }
23
24 // This class shows how client code uses the indexer.
25 class Program
26 {
27 static void Main(string[] args)
28 {
29 // Declare an instance of the SampleCollection type.
30 SampleCollection<string> stringCollection = new SampleCollection<string>();
31
32 // Use [] notation on the type.
33 stringCollection[0] = "Hello, World";
34 System.Console.WriteLine(stringCollection[0]);
35 }
36 }
复制代码

索引器和属性比较

属性

索引器

允许像调用公共数据成员一样调用方法。

允许对一个对象本身使用数组表示法来访问该对象内部集合中的元素。

可通过简单的名称进行访问。

可通过索引器进行访问。

可以为静态成员或实例成员。

必须为实例成员。

属性的 get 访问器没有参数。

索引器的 get 访问器具有与索引器相同的形参表。

属性的 set访问器包含隐式 value 参数。

除了值参数外,索引器的 set 访问器还具有与索引器相同的形参表。

支持对自动实现属性使用短语法。

不支持短语法。

接口中使用索引器

索引器可在接口上声明。 接口索引器的访问器与类索引器的访问器具有以下方面的不同:

  • 接口访问器不使用修饰符。

  • 接口访问器没有体。

因此,访问器的用途是指示索引器是读写、只读还是只写。

接口索引器访问器的示例:

复制代码
 1 public interface ISomeInterface
2 {
3 //...
4
5 string this[int index]
6 {
7 get;
8 set;
9 }
10 }
复制代码
 
如何实现借口索引器示例

复制代码
 1     // Indexer on an interface:
2 public interface ISomeInterface
3 {
4 // Indexer declaration:
5 int this[int index]
6 {
7 get;
8 set;
9 }
10 }
11
12 // Implementing the interface.
13 class IndexerClass : ISomeInterface
14 {
15 private int[] arr = new int[100];
16 public int this[int index] // indexer declaration
17 {
18 get
19 {
20 // The arr object will throw IndexOutOfRange exception.
21 return arr[index];
22 }
23 set
24 {
25 arr[index] = value;
26 }
27 }
28 }
29
30 class MainClass
31 {
32 static void Main()
33 {
34 IndexerClass test = new IndexerClass();
35 System.Random rand = new System.Random();
36 // Call the indexer to initialize its elements.
37 for (int i = 0; i < 10; i++)
38 {
39 test[i] = rand.Next();
40 }
41 for (int i = 0; i < 10; i++)
42 {
43 System.Console.WriteLine("Element #{0} = {1}", i, test[i]);
44 }
45
46 // Keep the console window open in debug mode.
47 System.Console.WriteLine("Press any key to exit.");
48 System.Console.ReadKey();
49 }
50 }
51 /* Sample output:
52 Element #0 = 360877544
53 Element #1 = 327058047
54 Element #2 = 1913480832
55 Element #3 = 1519039937
56 Element #4 = 601472233
57 Element #5 = 323352310
58 Element #6 = 1422639981
59 Element #7 = 1797892494
60 Element #8 = 875761049
61 Element #9 = 393083859
62 */
复制代码

在上例中,可以通过使用接口成员的完全限定名来使用显式接口成员实现。 例如: 

1 public string ISomeInterface.this 
2 {
3 }

但是,只有当类使用同一索引器签名实现一个以上的接口时,为避免多义性才需要使用完全限定名。 例如,如果 Employee 类实现的是两个接口 ICitizen 和IEmployee,并且这两个接口具有相同的索引器签名,则必须使用显式接口成员实现。 即,以下索引器声明: 

1 public string IEmployee.this 
2 {
3 }

在 IEmployee 接口上实现索引器,而以下声明:

1 public string ICitizen.this 
2 {
3 }

在 ICitizen 接口上实现索引器。

【本文由“白字先生”发布,2017年05月08日】

posted @ 2017-05-08 14:35 孙金棚 阅读(151) 评论(0) 推荐(0) 编辑
摘要: 1 <mce:script type="text/javascript"> 2 <!-- 3 //当天 4 function showToDay() 5 { 6 var Nowdate=new Date(); 7 M=Number(Nowdate.getMonth())+1 8 return Nowdate.getYear()+"-"+M+"-"+Nowdate.getDate(); 9 } 10 11 12 //本周第一天 13 function sh... 阅读全文
posted @ 2012-04-17 12:39 孙金棚 阅读(1147) 评论(1) 推荐(1) 编辑
摘要: 意图 用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。适用性 一组对象以定义良好但是复杂的方式进行通信。产生的相互依赖关系结构混乱且难以理解。 一个对象引用其他很多对象并且直接与这些对象通信,导致难以复用该对象。 想定制一个分布在多个类中的行为,而又不想生成太多的子类。结构图 Code 1 // Mediator 2 3 4 /* Notes: 5 * Consider a mediator as a hub, which objects that need to talk - 6 * but do... 阅读全文
posted @ 2012-04-16 15:37 孙金棚 阅读(376) 评论(1) 推荐(1) 编辑
摘要: 查询表达式基础通常,源数据会在逻辑上组织为相同种类的元素序列。 SQL 数据库表包含一个行序列。 与此类似,ADO.NET DataTable 包含一个DataRow对象序列。 在 XML 文件中,有一个 XML 元素“序列”(不过这些元素按分层形式组织为树结构)。 内存中的集合包含一个对象序列。应用程序始终将源数据视为一个 IEnumerable(Of T)或IQueryable(Of T)集合。 在 LINQ to XML 中,源数据显示为一个 IEnumerable<XElement >。 在 LINQ to DataSet 中,它是一个 IEnumerable<Dat 阅读全文
posted @ 2012-04-13 09:57 孙金棚 阅读(1181) 评论(0) 推荐(4) 编辑
摘要: 概述迭代器(Iterator)模式,又叫做游标(Cursor)模式。GOF给出的定义为:提供一种方法访问一个容器(container)对象中各个元素,而又不需暴露该对象的内部细节。 从定义可见,迭代器模式是为容器而生。很明显,对容器对象的访问必然涉及到遍历算法。你可以一股脑的将遍历方法塞到容器对象中去;或者根本不去提供什么遍历算法,让使用容器的人自己去实现去吧。这两种情况好像都能够解决问题。意图提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示。适用性1.访问一个聚合对象的内容而无需暴露它的内部表示。2.支持对聚合对象的多种遍历。3.为遍历不同的聚合结构提供一个统一的接 阅读全文
posted @ 2012-04-12 18:13 孙金棚 阅读(613) 评论(1) 推荐(1) 编辑
摘要: 概述LINQ,语言集成查询(Language INtegrated Query)是一组用于c#和Visual Basic语言的扩展。它允许编写C#或者Visual Basic代码以查询数据库相同的方式操作内存数据。LINQ定义了大约40个查询操作符,如select、from、in、where以及order by(C#)中。使用这些操作可以编写查询语句。不过,这些查询还可以基于很多类型的数据,每个数据类型都需要一个单独的LINQ类型。在 Visual Studio 中,可以用 Visual Basic 或 C# 为以下数据源编写 LINQ 查询:SQL Server 数据库、XML 文档、ADO 阅读全文
posted @ 2012-04-12 13:56 孙金棚 阅读(1351) 评论(8) 推荐(6) 编辑
摘要: 意图 将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤消的操作。适用性 1.抽象出待执行的动作以参数化某对象,你可用过程语言中的回调(c a l l b a c k )函数表达这种参数化机制。所谓回调函数是指函数先在某处注册,而它将在稍后某个需要的时候被调用。C o m m a n d 模式是回调机制的一个面向对象的替代品。 2.在不同的时刻指定、排列和执行请求。一个C o m m a n d 对象可以有一个与初始请求无关的生存期。如果一个请求的接收者可用一种与地址空间无关的方式表达,那么就可将负责该请求的命令对象传送给另一个... 阅读全文
posted @ 2012-04-09 12:33 孙金棚 阅读(1021) 评论(2) 推荐(2) 编辑
摘要: 意图 使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。适用性 1.有多个的对象可以处理一个请求,哪个对象处理该请求运行时刻自动确定。 2.你想在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。 3.可处理一个请求的对象集合应被动态指定。结构图 Code 1 // Chain Of Responsibility 2 3 /* Notes: 4 * The client sends a request and it will be operated on by one o... 阅读全文
posted @ 2012-04-09 09:25 孙金棚 阅读(1361) 评论(0) 推荐(1) 编辑
摘要: 意图 定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。Te m p l a t e M e t h o d 使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。实用性 1.一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现。 2.各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。这是O p d y k e 和J o h n s o n 所描述过的“重分解以一般化”的一个很好的例子[ O J 9 3 ]。首先识别现有代码中的不同之处,并且将不同之处分离为新的操作。最后,用一个调用这些新的操作的模板方法来替换这些不同的代码。 3.控制子类扩展。... 阅读全文
posted @ 2012-04-08 16:08 孙金棚 阅读(325) 评论(0) 推荐(0) 编辑
摘要: 意图 给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。适用性 1.当有一个语言需要解释执行, 并且你可将该语言中的句子表示为一个抽象语法树时,可使用解释器模式。而当存在以下情况时该模式效果最好。 2.该文法简单对于复杂的文法, 文法的类层次变得庞大而无法管理。此时语法分析程序生成器这样的工具是更好的选择。它们无需构建抽象语法树即可解释表达式, 这样可以节省空间而且还可能节省时间。 3.效率不是一个关键问题最高效的解释器通常不是通过直接解释语法分析树实现的, 而是首先将它们转换成另一种形式。例如,正则表达式通常被转换成状态机。但即使在这种情... 阅读全文
posted @ 2012-04-08 15:36 孙金棚 阅读(1005) 评论(2) 推荐(1) 编辑
点击右上角即可分享
微信分享提示