C# 中的索引器

本文深入探讨了C#中的索引器概念,详细介绍了属性与索引器之间的区别与联系,并通过实例展示了如何在类中设置索引器,以及如何在接口中声明索引器。文章强调了索引器在实现类似数组行为方面的优势,以及在创建集合类、处理大型文件和抽象有限资源时的灵活性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在C#中,有一个最令人感兴趣的地方就是类的索引器(indexer)。简单说来,所谓索引器就是一类特殊的属性,通过它们你就可以像引用数组一样引用自己的类。显然,这一功能在创建集合类的场合特别有用,而在其他某些情况下,比如处理大型文件或者抽象某些有限资源等,能让类具有类似数组的行为当然也是非常有用的。本文就会引领你设置类来采用索引器。但是,首先让我们概述下属性这个概念以便了解些必要的背景知识。

属性

假如你曾经用VB6编写过程序,那么你应该很熟悉属性方法才对,所谓属性方法其实就是特殊的类成员,它实现了对私有类域的受控访问。在C#语言中有两种属性方法,其一是get,通过它可以返回私有域的值,其二是set,通过它就可以设置私有域的值。比如说,以下面的代码为例,其间创建了一个FirstName 属性,由它控制对私有类成员firstname的访问:

 

class Person {

      private string firstname;

      public string FirstName {

           get {return firstname;}

           set {firstname = value;}

      }

}

属性声明可以如下编码:

Person p = new Person();

p.FirstName = "Lamont";

Console.WriteLine (p.FirstName); 

 

 

如你你所看到的那样,属性声明倒更像是域声明,只不过它还声明了两个特殊的成员,按照微软的说法就是所谓的访问函数(accessor)。当某一表达式的右边调用属性或者属性用作其他子程序(或者函数)的参数时即会调用get访问函数。反之,当表达式左边调用属性并且通过隐式传递value参数设置私有域值的情况下就会调用set访问函数。你可以创建只读属性,方法是省略set访问函数,这样任何设置属性的尝试都会产生编译错误。

采用索引器的益处

 

下面是它的结构

 

<modifier> <return type> this [argument list]

{

        get

       {

            // Get codes goes here

        }

       set

      {

           // Set codes goes here

       }

}

 

 

注:

 

modifier:修饰词,如private, public, protected or internal

 

this:在C#this是一个特殊的关键字,它表示引用类的当前实例。在这里它的意思是当前类的索引。

 

argument list:这里指索引器的参数。

 

说了半天咱们转到正题上来,那么为什么我要兜这个圈子呢?其实,这是因为类的索引器非常像属性,从代码上看也是这样。以下是具有索引器的类示例,通过索引器会返回一个字符串:

 

class Sample {

      public string this [int index] {

            get {return "You passed " + index; }

      }

} 

 

 

注意,这里的属性名是this,意思是回引类的当前实例,参数列表包含在方括号而非括号之内。还有,这是一个只读索引器。为了把它改成读/写类型,我又添加了一个set访问函数。在定义索引器的时候,你不一定只采用一个参数。索引器参数可以采用任何类型,不过int是通常采用也是最为合理的类型。同一类中还可能拥有一个以上的索引器(重载)。

如上定义了Sample类之后,我们就可以把索引器用作某种默认的属性,如下所示:

 

Sample s = new Sample();

Console.WriteLine(s[55]); 

 

 

属性和索引器

属性和索引器之间有好些差别:

类的每一个属性都必须拥有唯一的名称,而类里定义的每一个索引器都必须拥有唯一的签名(signature)或者参数列表(这样就可以实现索引器重载)。

属性可以是static(静态的)而索引器则必须是实例成员。

为索引器定义的访问函数可以访问传递给索引器的参数,而属性访问函数则没有参数。

接口

类似数组的行为常受到程序实现者的喜爱,所以你还可以为接口定义索引器,IList IDictionary集合接口都声明了索引器以便访问其存储的项目。

在为接口声明索引器的时候,记住声明只是表示索引器的存在。你只需要提供恰当的访问函数即可,不必包括范围修饰符。以下代码把索引器声明为接口IImplementMe的一部分:

 

interface IImplementMe {

      string this[int index]

      {

            get;

            set;

      } 

} 

 

相应实现的类则必须为IimplementMe的索引器具体定义getset访问函数。

以上就是有关索引器的一些基本概述了。现在你应该对索引器在你的开发中所具有的作用有了较深入的了解。

 

class SampleCollection<T>

{

    private T[] arr = new T[100];

    public T this[int i]

    {

        get

        {

            return arr[i];

        }

        set

        {

            arr[i] = value;

        }

    }

}

 

// This class shows how client code uses the indexer

class Program

{

    static void Main(string[] args)

    {

        SampleCollection<string> stringCollection = new SampleCollection<string>();

        stringCollection[0] = "Hello, World";

        System.Console.WriteLine(stringCollection[0]);

    }

}

<think>好的,我现在要解决用户关于C#索引使用方法和示例的问题。首先,我需要回忆一下C#索引的基本概念。根据引用[2],索引允许类像数组一样通过索引访问元素,这对于自定义集合类非常有用。用户需要具体的语法和示例,所以我得先整理索引的声明语法。 引用[4]中提到,声明索引的基本语法是使用this关键字,后跟参数和get、set访问。例如public string this[int index] { get { ... } set { ... } }。需要注意的是,索引只能用于实例成员,不能是静态的,这点在引用[1]里提到过。 接下来,我需要考虑如何给出一个清晰的示例。可能创建一个简单的类,比如StringList,内部用数组存储数据,然后通过索引访问。这样用户可以直观地看到如何实现get和set。此外,引用[3]指出索引可以有访问修饰符,并且get和set可以有不同的修饰符,但示例中可能先保持简单,使用public。 还要注意索引参数不仅可以是整数,也可以是其他类型,比如字符串。比如一个字典类可以用字符串作为键。这部分可以放在高级用法里,作为第二个示例,展示多类型参数的使用。 然后,用户可能想知道索引的实际应用场景,比如在集合类、数据封装或替代字典中的使用,根据引用[2]中的内容,这些都需要在相关问题和回答中提及。 最后,确保回答结构清晰,分点说明语法、示例和注意事项,并生成相关问题。检查引用的正确性,确保每个引用标识对应正确的来源。例如,引用[1]提到索引不能与this一起使用,但根据标准语法,索引正是使用this关键字,这里可能存在引用错误,需要确认。不过根据引用[4],正确语法是使用this,所以可能引用[1]的描述有误,或者用户引用有误,但作为回答者,应按照正确知识回答,可能引用[1]中的“不能与this关键字一起使用”是错误的,需要指出正确用法。</think>### C#索引使用方法及示例 #### 一、索引核心语法 索引允许类或结构体通过类似数组的语法访问成员,语法结构为: ```csharp public 返回类型 this[参数类型 参数名] { get { /* 返回值 */ } set { /* 设置值 */ } } ``` - 必须使用`this`关键字定义[^4] - 支持整型、字符串等多种参数类型[^2] - 可包含`get`和`set`访问(可设置不同访问权限)[^3] #### 二、基础使用示例 ```csharp public class StringList { private string[] _items = new string[10]; public string this[int index] { get => _items[index]; set => _items[index] = value; } } // 使用示例 var list = new StringList(); list[0] = "Hello"; // 通过索引赋值 Console.WriteLine(list[0]); // 输出:Hello ``` ▲ 实现类似数组的访问方式,封装内部数组操作 #### 三、高级应用示例 ```csharp public class TemperatureData { private float[] temps = new float[24]; // 多参数索引 public float this[int hour, TemperatureUnit unit] { get => unit == TemperatureUnit.Celsius ? temps[hour] : ConvertToFahrenheit(temps[hour]); set => temps[hour] = unit == TemperatureUnit.Celsius ? value : ConvertToCelsius(value); } } // 使用示例 var weather = new TemperatureData(); weather[12, TemperatureUnit.Fahrenheit] = 77.5f; ``` ▲ 支持多参数和单位转换的复合索引 #### 四、注意事项 1. 必须为实例成员,不能声明为`static`[^1] 2. 索引参数至少一个,不支持空参数[^3] 3. 可重载不同参数类型的索引[^4] 4. 访问可设置不同可见性: ```csharp public string this[int index] { internal get { ... } private set { ... } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值