一、索引器背景
索引器允许类或结构的实例就像数组一样进行索引。 无需显式指定类型或实例成员,即可设置或检索索引值。 索引器类似于属性,不同之处在于它们的访问器需要使用参数。
二、实现索引器
1.需要注意几点
- 使用索引器可以用类似于数组的方式为对象建立索引。
- get 取值函数返回值。 set 取值函数分配。
- this 关键字用于定义索引器。
- value 关键字用于定义 set 索引器所赋的值。
- 索引器不必根据整数值进行索引;由你决定如何定义特定的查找机制。
- 索引器可被重载。
- 索引器可以有多个形参,例如当访问二维数组时
2.具体实现如下:
代码实现如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Grammarly_Csharp
{
//实现字符串数组索引
class MyCollection<T>
{
private T[] arr = new T[100];
//索引器 通过get和set访问器进实现
public T this[int i]
{
get { return arr[i]; }
set { arr[i] = value; }
}
}
class Program
{
static void Main(string[] args)
{
MyCollection<string> myCollection = new MyCollection<string>();
myCollection[0] = "Hello";
Console.WriteLine(myCollection[0]); //Hello
Console.ReadLine();
}
}
}
为了支持这种情况,表达式主体成员提供了一种经过简化的语法。 自 C# 6 起,可以表达式主体成员的形式实现只读索引器,如以下示例所示。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Grammarly_Csharp
{
//实现字符串数组索引
class MyCollection<T>
{
// Declare an array to store the data elements.
private T[] arr = new T[100];
int nextIndex = 0;
// Define the indexer to allow client code to use [] notation.
//请注意,=> 引入了表达式主体,并未使用 get 关键字。
public T this[int i] => arr[i];
public void Add(T value)
{
if (nextIndex >= arr.Length)
throw new IndexOutOfRangeException($"The collection can hold only {arr.Length} elements.");
arr[nextIndex++] = value;
}
}
class Program
{
static void Main(string[] args)
{
MyCollection<string> myCollection = new MyCollection<string>();
myCollection.Add("Hello");
Console.WriteLine(myCollection[0]); //Hello
Console.ReadLine();
}
}
}
自 C# 7.0 起,get 和 set 访问器均可作为表达式主体成员实现。 在这种情况下,必须使用 get 和 set 关键字。 例如:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Grammarly_Csharp
{
//实现字符串数组索引
class MyCollection<T>
{
// Declare an array to store the data elements.
private T[] arr = new T[100];
// C#7.0之后,在语法实现上,要比上述两种简洁很多
public T this[int i]
{
get => arr[i];
set => arr[i] = value;
}
}
class Program
{
static void Main(string[] args)
{
MyCollection<string> myCollection = new MyCollection<string>();
myCollection[0] = "Hello";
Console.WriteLine(myCollection[0]); //Hello
Console.ReadLine();
}
}
}
三、属性和索引器之间的比较
索引器与属性相似。 除下表所示的差别外,对属性访问器定义的所有规则也适用于索引器访问器。
属性 | 索引器 |
---|---|
允许以将方法视作公共数据成员的方式调用方法。 | 通过在对象自身上使用数组表示法,允许访问对象内部集合的元素。 |
通过简单名称访问。 | 通过索引访问。 |
可为静态成员或实例成员。 | 必须是实例成员。 |
属性的 get 访问器没有任何参数。 | 索引器的 get 访问器具有与索引器相同的形参列表。 |
属性的 set 访问器包含隐式 value 参数。 | 索引器的 set 访问器具有与索引器相同的形参列表,value 参数也是如此。 |
通过自动实现的属性支持简短语法。 | 不支持简短语法。 |
以上就是今天的索引器的小结,觉得有用的可以收藏一下。
参考文献:
1. https://docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/indexers/index