logo
Home 女足世界杯决赛 使用索引器 - C#

使用索引器 - C#

  • 2026-01-20 03:44:43

索引器使你可从语法上方便地创建类、结构或接口,以便客户端应用程序可以像访问数组一样访问它们。 编译器会生成一个 Item 属性(或者如果存在 IndexerNameAttribute,也可以生成一个命名属性)和适当的访问器方法。 在主要目标是封装内部集合或数组的类型中,常常要实现索引器。 例如,假设有一个类 TempRecord,它表示 24 小时的周期内在 10 个不同时间点所记录的温度(单位为华氏度)。 此类包含一个 temps 类型的数组 float[],用于存储温度值。 通过在此类中实现索引器,客户端可采用 TempRecord 的形式(而非 float temp = tempRecord[4])访问 float temp = tempRecord.temps[4] 实例中的温度。 索引器表示法不但简化了客户端应用程序的语法;还使类及其目标更容易直观地为其它开发者所理解。

若要在类或结构上声明索引器,请使用 this 关键字,如以下示例所示:

// Indexer declaration

public int this[int index]

{

// get and set accessors

}

重要

通过声明索引器,可自动在对象上生成一个名为 Item 的属性。 无法从实例Item直接访问 属性。 此外,如果通过索引器向对象添加自己的 Item 属性,则将收到 CS0102 编译器错误。 要避免此错误,请使用 IndexerNameAttribute 重命名本文后面详述的索引器。

注解

索引器及其参数的类型必须至少具有和索引器相同的可访问性。 有关可访问性级别的详细信息,请参阅访问修饰符。

有关如何在接口上使用索引器的详细信息,请参阅接口索引器。

索引器的签名由其形参的数目和类型所组成。 它不包含索引器类型或形参的名称。 如果要在相同类中声明多个索引器,则它们的签名必须不同。

索引器未分类为变量;因此,索引器值不能按引用(作为 ref 或 out 参数)传递,除非其值是引用(即按引用返回。)

若要使索引器的名称可为其他语言所用,请使用 System.Runtime.CompilerServices.IndexerNameAttribute,如以下示例所示:

// Indexer declaration

[System.Runtime.CompilerServices.IndexerName("TheItem")]

public int this[int index]

{

// get and set accessors

}

此索引器被索引器名称属性重写,因此其名称为 TheItem。 默认情况下,默认名称为 Item。

示例 1

下列示例演示如何声明专用数组字段 temps 和索引器。 索引器可以实现对实例 tempRecord[i] 的直接访问。 若不使用索引器,则将数组声明为公共成员,并直接访问其成员 tempRecord.temps[i]。

public class TempRecord

{

// Array of temperature values

float[] temps =

[

56.2F, 56.7F, 56.5F, 56.9F, 58.8F,

61.3F, 65.9F, 62.1F, 59.2F, 57.5F

];

// To enable client code to validate input

// when accessing your indexer.

public int Length => temps.Length;

// Indexer declaration.

// If index is out of range, the temps array will throw the exception.

public float this[int index]

{

get => temps[index];

set => temps[index] = value;

}

}

请注意,当评估索引器访问时(例如在 Console.Write 语句中),将调用 get 访问器。 因此,如果不存在 get 访问器,则会发生编译时错误。

var tempRecord = new TempRecord();

// Use the indexer's set accessor

tempRecord[3] = 58.3F;

tempRecord[5] = 60.1F;

// Use the indexer's get accessor

for (int i = 0; i < 10; i++)

{

Console.WriteLine($"Element #{i} = {tempRecord[i]}");

}

使用其他值进行索引

C# 不将索引参数类型限制为整数。 例如,对索引器使用字符串可能有用。 通过搜索集合内的字符串并返回相应的值,可以实现此类索引器。 访问器可被重载,因此字符串和整数版本可以共存。

示例 2

下面的示例声明了存储星期几的类。

get 访问器采用字符串(星期几)并返回对应的整数。 例如,“Sunday”返回 0,“Monday”返回 1,依此类推。

// Using a string as an indexer value

class DayCollection

{

string[] days = ["Sun", "Mon", "Tues", "Wed", "Thurs", "Fri", "Sat"];

// Indexer with only a get accessor with the expression-bodied definition:

public int this[string day] => FindDayIndex(day);

private int FindDayIndex(string day)

{

for (int j = 0; j < days.Length; j++)

{

if (days[j] == day)

{

return j;

}

}

throw new ArgumentOutOfRangeException(

nameof(day),

$"Day {day} is not supported.\nDay input must be in the form \"Sun\", \"Mon\", etc");

}

}

使用示例 2

var week = new DayCollection();

Console.WriteLine(week["Fri"]);

try

{

Console.WriteLine(week["Made-up day"]);

}

catch (ArgumentOutOfRangeException e)

{

Console.WriteLine($"Not supported input: {e.Message}");

}

示例 3

下面的示例声明了使用 System.DayOfWeek 存储星期几的类。

get 访问器采用 DayOfWeek(表示星期几的值)并返回对应的整数。 例如,DayOfWeek.Sunday 返回 0,DayOfWeek.Monday 返回 1,依此类推。

using Day = System.DayOfWeek;

class DayOfWeekCollection

{

Day[] days =

[

Day.Sunday, Day.Monday, Day.Tuesday, Day.Wednesday,

Day.Thursday, Day.Friday, Day.Saturday

];

// Indexer with only a get accessor with the expression-bodied definition:

public int this[Day day] => FindDayIndex(day);

private int FindDayIndex(Day day)

{

for (int j = 0; j < days.Length; j++)

{

if (days[j] == day)

{

return j;

}

}

throw new ArgumentOutOfRangeException(

nameof(day),

$"Day {day} is not supported.\nDay input must be a defined System.DayOfWeek value.");

}

}

使用示例 3

var week = new DayOfWeekCollection();

Console.WriteLine(week[DayOfWeek.Friday]);

try

{

Console.WriteLine(week[(DayOfWeek)43]);

}

catch (ArgumentOutOfRangeException e)

{

Console.WriteLine($"Not supported input: {e.Message}");

}

可靠编程

提高索引器的安全性和可靠性有两种主要方法:

请确保结合某一类型的错误处理策略,以处理万一客户端代码传入无效索引值的情况。 在本文前面的第一个示例中,TempRecord 类提供了 Length 属性,使客户端代码能在将输入传递给索引器之前对其进行验证。 也可将错误处理代码放入索引器自身内部。 请确保为用户记录在索引器的访问器中引发的任何异常。

在可接受的程度内,为 get 和 set 访问器的可访问性设置尽可能多的限制。 这一点对 set 访问器尤为重要。 有关详细信息,请参阅限制访问器可访问性。

另请参阅

索引器

属性

Previous Post
《神界原罪2》主流职业构筑与培养手册
Copyright © 2088 cctv5在线直播世界杯_世界杯世界 - qw-cp.com All Rights Reserved.
友情链接