【ArchSummit架构师峰会】探讨数据与人工智能相互驱动的关系>>> 了解详情
写点什么

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

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

关注

评论

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

慎思笃行,兴业致远:金融行业的数据之道

脑极体

金融数据

代码随想录Day31 - 贪心算法(一)

jjn0703

Nginx服务器上安装SSL证书?

百度搜索:蓝易云

nginx 运维 https SEO ssl

获评最高级别权威认证!融云通过中国信通院「办公即时通信软件安全能力」评测

融云 RongCloud

通信 即时通讯 办公 融云 百幄

代码随想录Day29 - 回溯(五)

jjn0703

致敬图灵!HashData拥抱数据智能新时代!

酷克数据HashData

MedicalGPT:基于LLaMA-13B的中英医疗问答模型(LoRA)

汀丶人工智能

人工智能 自然语言处理 LoRa llama LLM模型

Dify.AI 接入 Claude2 模型:支持 100K token 上下文,登录即免费获得 1000 次消息额度

Dify

开源 更新 LLMOps

对线面试官-线程池连环问

派大星

线程池工作原理 Java 面试题

项目管理的成功秘诀:架构评审的力量

乐思项目管理

架构评审 #项目管理

Java Stream 源码分析

java易二三

Java 编程 计算机

死磕Java八股成功拿下Offer,结果背调没过...

程序员小毕

程序员 面试 高并发 架构师 java面试

Tomcat服务器上安装SSL证书?

百度搜索:蓝易云

tomcat Linux https SEO ssl

2023-07-29:给你一个由数字组成的字符串 s,返回 s 中独特子字符串数量。 其中的每一个数字出现的频率都相同。

福大大架构师每日一题

福大大架构师每日一题

项目管理中的'右转必停'原则:慎重决策与风险管理

乐思项目管理

项目管理 #观察生活

代码随想录Day28 - 回溯(四)

jjn0703

彻底学透分布式事务看这篇笔记就够了!

小小怪下士

Java 程序员 分布式 分布式事务

代码随想录Day30 - 回溯(六)

jjn0703

高可用三大利器 — 熔断、限流和降级

Java研究者

架构 高可用 熔断 限流 java 架构

使用APP源码搭建直播网站难不难

山东布谷网络科技

APP开发 直播APP源码

项目管理中的测试:确保项目成功的关键环节

乐思项目管理

项目管理 软件测试

一个写了3年半flutter的小伙,突然写了2个月uniapp的感悟!

编程的平行世界

uni-app Vue 前端 Flutter Android Apk

Apache服务器上安装SSL证书?

百度搜索:蓝易云

Apache Linux https SEO ssl

代码随想录Day32 - 贪心算法(二)

jjn0703

在 Amazon EMR 上构建实时数据湖

亚马逊云科技 (Amazon Web Services)

Amazon EMR

C++中互斥锁的使用

二哈侠

Spring系列之HikariCP连接池

java易二三

编程 程序员 Spring Boot 计算机 spring类型转换

项目管理中的代码评审:一种有效的实施策略和常见问题解析

乐思项目管理

代码评审 #项目管理

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