写点什么

通过索引器简化 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:562047
用户头像

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

关注

评论

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

语音数据集在智能语音搜索中的应用与挑战

数据堂

供应链共舞:数字化协同推动服装企业商品计划的无缝衔接

第七在线

左耳听风 - 编程的本质「读书打卡 day 10」

Java 工程师蔡姬

读书笔记 程序员 个人成长 编程的本质 职业发展

语音数据集在智能语音助手中的应用与挑战

数据堂

文心一言 VS 讯飞星火 VS chatgpt (181)-- 算法导论13.4 4题

福大大架构师每日一题

福大大架构师每日一题

喜报!博睿数据荣获数据猿“年度创新服务企业奖、年度创新服务产品奖”

博睿数据

可观测性 博睿数据 运维监控

一文了解字节跳动消息队列演进之路

字节跳动云原生计算

大数据 云原生 消息列队

美的楼宇科技携手火山引擎,共筑边缘云新型生态圈

火山引擎边缘云

边缘计算 智慧园区 智慧建筑 边缘云

Google推广之关键字匹配类型

九凌网络

1688商品数据API接口的数据分析与挖掘技巧

Noah

自助式可视化开发,ETLCloud的集成之路

RestCloud

可视化 ETL

“一次不过、免费再考” 限时活动开启,快来考取亚马逊云科技认证吧!

亚马逊云科技 (Amazon Web Services)

培训与认证

华为云DTSE助力无锡云数IoT系统:打造超可靠数字化之源

华为云开发者联盟

云计算 后端 华为云 华为云开发者联盟 华为云DTSE

OpenHarmony开源GPU库Mesa3D适配说明

Laval小助手

OpenHarmony

每日一题:LeetCode-297. 二叉树的序列化与反序列化

Geek_4z9ami

面试 算法 LeetCode 二叉树 DFS

腾讯云ES RAG最佳实践:向量+文本混合搜索的相关性调优

腾讯云大数据

ES

阿里云PolarDB开发者大会首度召开,让数据库开发像“搭积木”一样简单

阿里云瑶池数据库

数据库 云计算 阿里云 云原生 开发者大会

OpenHarmony图形HDI基础适配及点屏

Laval小助手

数字先锋| 让群众健康更有“医靠”,天翼云为喀什中医院开出“上云妙方”!

天翼云开发者社区

云计算 大数据

数字先锋| 向“新”而生!天翼云携手中化信息按下化工行业变革加速器

天翼云开发者社区

云计算 数字化转型 云平台

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