0

0

C#的索引器(Indexer)如何实现类似数组的访问?

小老鼠

小老鼠

发布时间:2025-08-16 09:05:01

|

272人浏览过

|

来源于php中文网

原创

索引器通过this关键字定义,允许对象像数组或字典一样使用[]访问内部数据;2. 其参数类型不限于int,可为string、guid或自定义类型,实现灵活的数据访问方式;3. 易忽略的细节包括边界检查(防止越界异常)、键不存在时的处理逻辑(返回null或抛异常)、性能影响(避免复杂操作)以及支持重载(不同参数列表的多个索引器)。

C#的索引器(Indexer)如何实现类似数组的访问?

C#中的索引器(Indexer)提供了一种非常直观且类似数组的语法,允许我们通过指定一个或多个索引或键来访问对象内部的数据。它本质上让类的实例能够像数组或字典那样,使用方括号

[]
来存取其内部的元素。

解决方案

要实现一个索引器,你需要在类中定义一个特殊的成员,它看起来很像一个属性,但使用了

this
关键字并带有一个参数列表。这个参数列表就是你用来访问数据的“索引”或“键”。

一个基本的索引器定义通常是这样的:

public class MyCollection
{
    private string[] data = new string[10]; // 内部存储

    // 定义一个索引器,允许通过整数索引访问
    public string this[int index]
    {
        get
        {
            // 确保索引在有效范围内
            if (index >= 0 && index < data.Length)
            {
                return data[index];
            }
            throw new IndexOutOfRangeException("索引超出范围。");
        }
        set
        {
            // 确保索引在有效范围内
            if (index >= 0 && index < data.Length)
            {
                data[index] = value;
            }
            else
            {
                throw new IndexOutOfRangeException("索引超出范围。");
            }
        }
    }

    // 也可以定义一个只读的索引器
    public string this[string key]
    {
        get
        {
            // 假设这里有一个更复杂的查找逻辑,比如根据字符串键查找
            // 为了示例简单,这里直接返回一个固定值
            if (key == "first") return data[0];
            if (key == "last") return data[data.Length - 1];
            return null; // 或者抛出异常
        }
    }
}

在使用时,就像操作数组一样:

MyCollection collection = new MyCollection();
collection[0] = "Hello"; // 使用set访问器
string item = collection[0]; // 使用get访问器
Console.WriteLine(item); // 输出: Hello

// 使用字符串索引器
string firstItem = collection["first"];
Console.WriteLine(firstItem); // 输出: Hello

这里的

this
关键字并不代表类的当前实例本身,而是表示你正在为这个类的实例定义一个索引访问器。
get
set
访问器的工作方式与属性的访问器类似,
value
关键字在
set
访问器中代表赋给索引器的值。

索引器与属性:它们的核心差异在哪里?

我个人觉得,很多人刚接触索引器时,会下意识地把它和属性混淆。但实际上,它们的设计哲学是完全不同的。属性(Property)是为了封装一个单一的、命名明确的数据成员,比如一个人的

Name
、一个产品的
Price
。你通过
.
操作符加上属性名来访问它,每次访问都代表一个具体的、独立的“值”。

而索引器呢,它的核心是提供一种“集合式”的访问模式。它没有一个具体的名称,而是通过

this
关键字来表示它就是这个类实例的“默认访问方式”,并且总是需要一个或多个参数(也就是索引或键)来指定你想要访问集合中的哪一个元素。你可以把它想象成给你的对象一个“数组接口”或者“字典接口”。

举个例子,你不会有一个属性叫

MyObject.Item[0]
,你会有一个属性叫
MyObject.FirstItem
或者
MyObject.CurrentItem
。但如果你想访问
MyObject
内部的一个列表的第N个元素,用
MyObject[N]
就显得非常自然和直观,这就是索引器的用武之地。

来福FM
来福FM

来福 - 你的私人AI电台

下载

除了整数,索引器还能用什么来访问数据?

这点其实挺有意思的,它让索引器远比想象中灵活。索引器参数的类型并不局限于

int
。你可以使用任何合法的C#数据类型作为索引器的参数,比如
string
Guid
,甚至是自定义的类实例。这意味着你可以创建像字典一样通过字符串键来访问数据的对象,而不仅仅是像数组那样通过数字索引。

例如,如果你正在构建一个配置管理器类,你可能希望通过配置项的名称(字符串)来访问其值:

public class ConfigurationManager
{
    private Dictionary settings = new Dictionary();

    public string this[string key]
    {
        get
        {
            if (settings.ContainsKey(key))
            {
                return settings[key];
            }
            // 考虑返回null、抛出异常或返回默认值
            return null; 
        }
        set
        {
            settings[key] = value;
        }
    }
}

这样,你就可以写

ConfigurationManager config = new ConfigurationManager(); config["DatabaseConnection"] = "connection_string";
这种代码,读起来非常直观。这种灵活性使得索引器在模拟各种数据结构(如稀疏数组、矩阵、自定义映射表)时变得异常强大。

实现自定义索引器时,有哪些细节容易被忽略?

说实话,我见过不少新手在写索引器时,直接就忽略了一些关键的细节,结果一运行就炸。这些细节看似简单,却是决定代码健壮性的关键。

一个最常见的疏忽是边界检查。特别是当你的索引器使用

int
作为参数时,你内部很可能是在操作一个数组或列表。如果用户传入一个负数索引,或者一个超出你内部集合大小的索引,你必须进行适当的检查,并抛出
IndexOutOfRangeException
,而不是让程序因为内部数组访问越界而崩溃。这就像是你给用户提供了一个“门”,你得确保他们不会撞到墙上。

另一个常被忽略的点是对非

int
类型索引的键处理。比如,你用
string
作为键,那么当用户请求一个不存在的键时,你的
get
访问器应该怎么处理?是返回
null
?抛出
KeyNotFoundException
?还是返回一个默认值?这取决于你的业务逻辑和设计意图。没有统一的答案,但必须明确地处理。我个人倾向于在明确预期键存在的情况下抛出异常,否则返回
null
或者一个指示“未找到”的特定值。

还有,性能考量。虽然索引器语法简洁,但它背后执行的逻辑可能并不简单。如果你的

get
set
访问器内部包含了复杂的计算、数据库查询或者网络请求,那么频繁地通过索引器访问数据可能会成为性能瓶颈。在使用索引器时,要清楚它背后可能隐藏的开销,避免在高性能要求的场景下滥用。

最后,别忘了索引器也是可以重载的。你可以为一个类定义多个索引器,只要它们的参数列表(类型和数量)不同就行。这使得你可以通过不同的“维度”或“键类型”来访问同一份数据,比如一个

this[int index]
用于顺序访问,一个
this[string name]
用于按名称访问。这提供了很大的灵活性,但也增加了设计的复杂性,需要确保逻辑清晰。

相关专题

更多
数据类型有哪几种
数据类型有哪几种

数据类型有整型、浮点型、字符型、字符串型、布尔型、数组、结构体和枚举等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

303

2023.10.31

php数据类型
php数据类型

本专题整合了php数据类型相关内容,阅读专题下面的文章了解更多详细内容。

222

2025.10.31

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

317

2023.08.02

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

231

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

436

2024.03.01

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

257

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

208

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1465

2023.10.24

高德地图升级方法汇总
高德地图升级方法汇总

本专题整合了高德地图升级相关教程,阅读专题下面的文章了解更多详细内容。

40

2026.01.16

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
10分钟--Midjourney创作自己的漫画
10分钟--Midjourney创作自己的漫画

共1课时 | 0.1万人学习

Midjourney 关键词系列整合
Midjourney 关键词系列整合

共13课时 | 0.9万人学习

AI绘画教程
AI绘画教程

共2课时 | 0.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号