2天时间,聊今年最热的 Agent、上下文工程、AI 产品创新等话题。2025 年最后一场~ 了解详情
写点什么

通过索引器简化 C#类型信息访问

  • 2008-07-13
  • 本文字数:1899 字

    阅读完需:约 6 分钟

前言

作为一个有别于 Java、Ruby 等语言的一个特性,C#可以用索引器(Indexer)将类型本身以对象数组的形式供外部使用。下面是一个对比:(为了简化,略去了边界检查)

不难看出通过引入索引器,我们的目标类型DataAccess在涉及到根据编号检索的时候看上去更接近一个数组的样子,客户程序的开发人员不用关心具体的方法名称是GetData/GetInternalData或者是SetData/ UpdateData,仅仅把它当成一个数组就可以了,编码上也更加简洁、直观。

但索引器提供的检索能力不仅单纯面向一个一维数组,我们可以用它检索多维数组、内存空间数据(Space Data, 2D 或 3D,如果您的应用是面向时空穿梭的话,完全可以扩展至 4D)、复杂的数据结构(树、图、语义网络)、多因素的计算结果… … 只要类型的封装人员和使用人员就每个索引项的含义达成一致即可。例如:下面是对法定公历节日信息访问的类型:

是不是感觉上访问GregorianCalendarFixture的时候就像我们面对着一个DataTimePicker控件一样?

实现多途径的数据项检索

上面都是单个途径看目标类型的数据组织,但就像我们看待一个人一样,评价它往往会通过不同途径,同时每个途径可能也是一组对象或一个复杂的数据结构系统,而且每个检索的指标是不同的数据类型。同样出于封装和简化客户程序使用的考虑,我们可以继续用索引器完成。

比如:我们希望提供按照城市 ID、中文拼音缩写、城市名称枚举 3 种方式获得其气温情况,为了便于客户程序使用,我们重载出了一系列索引器,这样一方面客户程序可以根据上下文用不同类型的键值访问,也省去了解具体应该使用哪个函数的繁琐。

实现类似 RDBMS 中联合主键或唯一性索引的访问

通过“索引器”这个名称我们会很自然的联系到 RDBMS(关系数据库)中的索引,就如我们在设计数据库逻辑结构的过程一样,往往为了唯一标注每条记录,常常会用到主键或唯一性索引,而构成他们的属性(列)可能是 1 项也可能是几项的联合。.NET 平台为了跨层调用的方便,从一开始就支持离线的 DataSet 和基于 DOM 的 XML 解析数据,随着.NET 平台升级到 2.0,对象化的配置类型也可以提供基于内存缓冲信息的访问。应用可能要求包装类型提供基于联合索引的查询(尤其对于属性较多、关系复杂的实体),而索引器又成了一个非常优雅的封装方式。

比如:一个员工实体包括“FirstName”、“FamilyName”、“Title”三个属性,我们需要包装一个 Staff 类型管理全部的员工信息。

同时根据 UI 绑定或其他功能检索的需要,我们会根据他的联合主键(FirstName + FamilyName)提供一个索引器,用它访问具体的员工记录。示例如下:

通过委托传递索引规则

如上文,对于检索规则固定的情况而言,我们可以通过在索引器内部硬编码完成,但如果要完成一些更为公共的类库,我们往往还需要“授之以渔”,即除了告诉他“要检索”这个任务之外,还要把检索策略和规则告诉它。这方面 C#是非常有优势的,因为它有对象化的托管委托类型(delegate),而且.NET Framework FCL 部分也提供了很多现成的委托,所以我们不妨善加利用。

这时候, 我们会发现索引器的功能更加强大,我们就像在使用 SQL 语句的 WHERE 子句一样,以灵活的方式对目标数据根据需要筛选。

不过,我们在实际使用中 WHERE 子句可能还会包括不只一条的限制条件,索引器一样可以完成。例如,定义为下列形式:

LINQ 时代的索引器

乍一看,索引器似乎已经越来越接近于 LINQ 通过 Lamada 表达式完成的功能,不过有些区别:

  • 定位上索引器一般面向单条检索结果,而不是批量结果(尽管我们可以让索引器返回一个IEnumerable<t></t>
  • 从封装和客户程序使用的角度看,LINQ 有各种内置并被优化的 LINQ to 系列,而索引器给客户程序是一种更为贴近业务语义、更加直观的形式,因为客户程序无需写 LINQ 查询,只是按照键值检索即可

不过,把两者结合使用倒是一个非常不错的组合,索引器做接口、LINQ 完成内部检索逻辑,客户程序在无需记住具体方法名称的前提下,按照键值检索即可,索引器内部则依托 LINQ to 系列的基础,提供对各种异构数据源的访问。

小结

就像我们设计接口时会根据业务领域,把类型的职能分解一样,操作类型的时候同样, 一样可以根据访问内容不同,选择使用不同的访问方法,比如:

  • 索引器:承担各种检索和查找的工作
  • 属性(Property): 承担“它的…特性是…”或“它们的…特质是…”的工作,用来标注某个实例特性(成员属性)或静态特性(静态属性)
  • 普通的方法:承担“让它处理……”的职能
  • 而事件定位于“当……发生的时候,需要作些……”

受到惯性影响,我们常常把索引器作为一个仅仅按照编号反馈结果的入口,但就如 SQL 中的 WHERE 子句, 我们其实可以做很多。善用之,它会令我们的程序更加亲切、更加清晰。

2008-07-13 06:562210
用户头像

发布了 61 篇内容, 共 14.3 次阅读, 收获喜欢 0 次。

关注

评论

发布
暂无评论
发现更多内容

DApp开发全流程解析:模式设计、功能参考与合约管理实践

区块链软件开发推广运营

交易所开发 dapp开发 链游开发 公链开发 公链开发代币开发

鸿蒙带来的机会比想象中更大

最新动态

自己动手,从零开始编写Raft算法来实现分布式一致性算法

程序员高级码农

程序员 分布式 算法

深入解析 Spring AI 系列:解析请求参数处理

不在线第一只蜗牛

人工智能 spring

模型即组件的技术实现路径 ——iVX 量子化架构对 GPT-4o/Mediapipe 的封装解析

代码制造者

低代码 组件化 封装 组件化开发

Arthas getstatic(查看类的静态属性 )

刘大猫

监控 Arthas 监控工具 getstatic 查看类静态属性

通义灵码2.5智能体模式联合MCP:打造自动化菜品推荐平台,实现从需求到部署的全流程创新

穿过生命散发芬芳

MCP 通义灵码2.5

借助 CodeBuddy,轻松打造「一分钟冥想」App

繁依Fanyi

【HarmonyOS 5】鸿蒙星闪NearLink详解

GeorgeGcs

打卡习惯,记录坚持:我用 CodeBuddy 做了个毛玻璃风格的习惯打卡小应用

繁依Fanyi

一次对话,让我10分钟打造一款拥有玻璃拟态风格的二维码生成大师

繁依Fanyi

使用kookeey代理IP配置Undetectable指纹浏览器教程

kookeey代理严选

代理IP 跨境电商 代理商 kookeey代理 Undetectable指纹浏览器

CouchDB 可观测最佳实践

观测云

couchdb

全职接单后才发现,其实不只是技术重要

程序员郭顺发

鸿蒙电脑正式发布!新机用户专享“鸿蒙有礼”,800元权益礼包限时领取

最新动态

对比解读发币平台:从野蛮爆发走向精细化运营

区块链软件开发推广运营

交易所开发 dapp开发 链游开发 代币开发 交易所开发公链开发

NotebookLM 推出移动版本,音频概览支持实时互动;豆包 AI 耳机支持外教语音智能体 Owen丨日报

声网

高能预警!Community Day 20+议题大公开

声网

Flink从入门到实战,经历了30个日日夜夜,终于悟道了!

程序员高级码农

大数据 flink 程序员

ES 调优帖:关于索引合并参数 index.merge.policy.deletePctAllowed 的取值优化

极限实验室

Elastic Search

「今日一句」情绪签语 App:一次与 CodeBuddy 的共创之旅

繁依Fanyi

虚拟币制度钱包开发:功能设计与成本全解析

区块链软件开发推广运营

交易所开发 dapp开发 链游开发 代币开发 交易所开发公链开发

RocketMQ实战—订单系统面临的技术挑战

量贩潮汐·WholesaleTide

数据库 RocketMQ

Arthas 全攻略:让调试变得简单

刘大猫

人工智能 算法 监控 Arthas 监控工具

永久免费!专为 Apache Doris 打造的可视化数据管理工具 SelectDB Studio V1.1.0 重磅发布!

SelectDB

数据库 大数据 数据分析 实时数仓 可视化工具

《算法导论(第4版)》阅读笔记:p91-p94

codists

算法

【浪潮海岳inDatax数据中台专栏】主数据管理中基于属性的物料编号生成技术

inBuilder低代码平台

数据仓库是什么?常见问题解答

镜舟科技

数据仓库 数据湖 OLAP 数据模型 数据存储

Doris Manager 24.3 版本正式发布,增强集群巡检能力

SelectDB

Apache 数据库 数据分析 实时数仓 OLAP

Nuxt的SEO实践

溪抱鱼

typescript nuxt

借助 CodeBuddy,我轻松开发出三分钟读书 App

繁依Fanyi

通过索引器简化C#类型信息访问_.NET_王翔_InfoQ精选文章