【.net 深呼吸】细说CodeDom(7):索引器
在开始正题之前,先补充一点前面的内容。
在方法中,如果要引用方法参数,前面的示例中,老周使用的是 CodeVariableReferenceExpression 类,它用于引用变量,也适用于引用方法参数。除了这个类,还可以使用 CodeArgumentReferenceExpression 类,这个类是专为方法参数引用而设计,其实用起来也和变量引用一样。请看看下面的例子。
CodeMemberMethod m = new CodeMemberMethod();
m.Name = "Test";
// 输出参数
CodeParameterDeclarationExpression p = new CodeParameterDeclarationExpression(typeof(int), "a");
p.Direction = FieldDirection.Out;
m.Parameters.Add(p);
// 赋值语句
CodeAssignStatement ass = new CodeAssignStatement();
ass.Left = new CodeArgumentReferenceExpression(p.Name);
ass.Right = new CodePrimitiveExpression();
m.Statements.Add(ass); CodeDomProvider provider = CodeDomProvider.CreateProvider("cs");
CodeGeneratorOptions opt = new CodeGeneratorOptions
{
BracingStyle = "C"
};
provider.GenerateCodeFromMember(m, Console.Out, opt);
Test 方法带有一个输出参数a,int类型,方法体中给参数a赋值。上面代码执行后,生成的代码如下图所示。

============================================
好,进入主题,今天咱们来聊一聊“索引”这玩意儿。通常,使用索引的类型有:数组、List、哈希表/字典等。使用索引的类型成员有索引器。索引器可能不多见,其实跟属性很像。
先来看看数组的初始化方法。初始化数组是一类表达式,主要用到 CodeArrayCreateExpression 类。
看一个简单的例子。
CodeArrayCreateExpression ce = new CodeArrayCreateExpression();
ce.CreateType = new CodeTypeReference(typeof(string));
ce.Size = ; CodeDomProvider p = CodeDomProvider.CreateProvider("C#");
p.GenerateCodeFromExpression(ce, Console.Out, null);
CreateType 属性用来指定数组的类型,本例中类型为string,Size属性指定数组的大小。得到的代码如下图所示。

由于不是所有语言都支持多维数组和嵌套数组,所以,目前来说,CodeDom并不能实例化多维数组。不过也没关系,毕竟N维数组和嵌套数组很少会用得上。
有时候,在实例化数组对象的时候就顺便对元素进行初始化,可以将初始化元素的表达式添加到 Initializers 集合中。请看下面例子。
CodeArrayCreateExpression arrce = new CodeArrayCreateExpression();
arrce.CreateType = new CodeTypeReference(typeof(int));
// 初始化元素
arrce.Initializers.Add(new CodePrimitiveExpression());
arrce.Initializers.Add(new CodePrimitiveExpression());
arrce.Initializers.Add(new CodePrimitiveExpression());
// 声明变量
CodeVariableDeclarationStatement vd = new CodeVariableDeclarationStatement();
vd.Name = "x";
vd.Type = new CodeTypeReference(typeof(int[]));
vd.InitExpression = arrce;
最后使用 CodeVariableDeclarationStatement 产生一句完整的变量声明语句,初始化变量时就用CodeArrayCreateExpression表达式。
生成的代码如下图所示。

要访问某个数组变量的指定索引处的值,可以用 CodeArrayIndexerExpression 类。
CodeArrayIndexerExpression aiexp = new CodeArrayIndexerExpression();
aiexp.TargetObject = new CodeVariableReferenceExpression("x");
aiexp.Indices.Add(new CodePrimitiveExpression());
TargetObject属性用来设置对数组变量的引用,Indices集合用来添加索引引用表达式,数组的索引都是整数,所以,应当用以下表达式:
new CodePrimitiveExpression(<整数值>)
上面示例生成的代码如下图所示。

=================================================
下面咱们看看索引器。
访问索引器最典型的一个应用是字典。下面例子将生成三个语句,其中,第一句是声明被初始化一个字典变量,第二句和第三句都是向字典变量添加元素。
// 声明并初始化字典变量
CodeVariableDeclarationStatement vd = new CodeVariableDeclarationStatement();
vd.Type = new CodeTypeReference(typeof(Dictionary<string, string>));
vd.Name = "dic";
vd.InitExpression = new CodeObjectCreateExpression(typeof(Dictionary<string, string>)); // 给字典对象添加元素
// 左边:索引引用
// 右边:值
CodeAssignStatement ass = new CodeAssignStatement();
ass.Left = new CodeIndexerExpression(new CodeVariableReferenceExpression(vd.Name), new CodePrimitiveExpression("a"));
ass.Right = new CodePrimitiveExpression("cake");
CodeAssignStatement ass1 = new CodeAssignStatement();
ass1.Left = new CodeIndexerExpression(new CodeVariableReferenceExpression(vd.Name), new CodePrimitiveExpression("b"));
ass1.Right = new CodePrimitiveExpression("bird"); CodeDomProvider prd = CodeDomProvider.CreateProvider("cs");
prd.GenerateCodeFromStatement(vd, Console.Out, null);
prd.GenerateCodeFromStatement(ass, Console.Out, null);
prd.GenerateCodeFromStatement(ass1, Console.Out, null);
引用某个实例的索引器,应使用 CodeIndexerExpression 类。TargetObject属性用来指定要引用的对象,通常是变量引用,Indices属性是索引集合,用来指定要访问的索引。这些属性的值可以直接向CodeIndexerExpression类的构造函数传递。
本例生成的代码如下。
System.Collections.Generic.Dictionary<string, string> dic = new System.Collections.Generic.Dictionary<string, string>();
dic["a"] = "cake";
dic["b"] = "bird";
如果要给自定义的类型声明索引器,要用 CodeMemberProperty 类,因为索引器与属性相似。还是用例子说话吧。
CodeTypeDeclaration td = new CodeTypeDeclaration("Sample");
td.Attributes = MemberAttributes.Public;
// 索引器
CodeMemberProperty mb = new CodeMemberProperty();
mb.Type = new CodeTypeReference(typeof(string));
mb.Name = "item";
mb.Attributes = MemberAttributes.Public | MemberAttributes.Final;
// 索引参数
mb.Parameters.Add(new CodeParameterDeclarationExpression(typeof(int), "k"));
td.Members.Add(mb);
CodeDomProvider provider = CodeDomProvider.CreateProvider("cs");
provider.GenerateCodeFromType(td, Console.Out, null);
这里有个地方要注意,就是索引器成员的名字,为了兼容各种语言,较合适的做法是把它命名为“item”或“Item”(不分大小写),这样一来,生成C#代码时,就能够生成 this[int k] 这样的语法,只有这样的语法才能被认为是索引器。
生成的代码如下图所示。

好了,今天对索引器代码生成相关的内容就扯到这里了,下一篇文章,老周就继续和大家聊聊条件语句与循环语句。
开饭了……
【.net 深呼吸】细说CodeDom(7):索引器的更多相关文章
- 【.net 深呼吸】细说CodeDom(1):结构大观
CodeDom 是啥东东?Html Dom听过吧,XML Dom听过吧.DOM一般可翻译为 文档对象模型,那 Code + DOM呢,自然是指代码文档模型了.如果你从来没接触过 CodeDom,你大概 ...
- C# 索引器,实现IEnumerable接口的GetEnumerator()方法
当自定义类需要实现索引时,可以在类中实现索引器. 用Table作为例子,Table由多个Row组成,Row由多个Cell组成, 我们需要实现自定义的table[0],row[0] 索引器定义格式为 [ ...
- C#基础回顾(三)—索引器、委托、反射
一.前言 ------人生路 ...
- C#索引器
索引器允许类或者结构的实例按照与数组相同的方式进行索引取值,索引器与属性类似,不同的是索引器的访问是带参的. 索引器和数组比较: (1)索引器的索引值(Index)类型不受限制 (2)索引器允许重载 ...
- C#之索引器
实际中不使用这个东西,只做了解 using System; using System.Collections.Generic; using System.Linq; using System.Text ...
- C#属性-索引器-里氏替换-多态-虚方法-抽象-接口-泛型-
1.属性 //属性的2种写法 public class person { private string _name; public string Name { get { return _name; ...
- 《精通C#》索引器与重载操作符(11.1-11.2)
1.索引器方法结构大致为<modifier><return type> this [argument list],它可以在接口中定义: 在为接口声明索引器的时候,记住声明只是表 ...
- 描述一下C#中索引器的实现过程,是否只能根据数字进行索引?
不是.可以用任意类型. 索引器是一种特殊的类成员,它能够让对象以类似数组的方式来存取,使程序看起来更为直观,更容易编写. 1.索引器的定义 C#中的类成员可以是任意类型,包括数组和集合.当一个类包含了 ...
- C# 索引器使用总结
1.索引器(Indexer): 索引器允许类或者结构的实例按照与数组相同的方式进行索引.索引器类似于属性,不同之处在于他们的访问采用参数. 最简单的索引器的使用 /// <summary> ...
随机推荐
- Fis3的前端工程化之路[三大特性篇之声明依赖]
Fis3版本:v3.4.22 Fis3的三大特性 资源定位:获取任何开发中所使用资源的线上路径 内容嵌入:把一个文件的内容(文本)或者base64编码(图片)嵌入到另一个文件中 依赖声明:在一个文本文 ...
- 学习ASP.NET Core, 怎能不了解请求处理管道[5]: 中间件注册可以除了可以使用Startup之外,还可以选择StartupFilter
中间件的注册除了可以借助Startup对象(DelegateStartup或者ConventionBasedStartup)来完成之外,也可以利用另一个叫做StartupFilter的对象来实现.所谓 ...
- 【Python五篇慢慢弹】快速上手学python
快速上手学python 作者:白宁超 2016年10月4日19:59:39 摘要:python语言俨然不算新技术,七八年前甚至更早已有很多人研习,只是没有现在流行罢了.之所以当下如此盛行,我想肯定是多 ...
- 你真的会玩SQL吗?之逻辑查询处理阶段
你真的会玩SQL吗?系列目录 你真的会玩SQL吗?之逻辑查询处理阶段 你真的会玩SQL吗?和平大使 内连接.外连接 你真的会玩SQL吗?三范式.数据完整性 你真的会玩SQL吗?查询指定节点及其所有父节 ...
- Twproject Gantt开源甘特图功能扩展
1.Twproject Gantt甘特图介绍 Twproject Gantt 是一款基于 jQuery 开发的甘特图组件,也可以创建其它图表,例如任务树(Task Trees).内置编辑.缩放和 CS ...
- .Net语言 APP开发平台——Smobiler学习日志:手机应用的TextTabBar快速实现方式
参考页面: http://www.yuanjiaocheng.net/webapi/create-crud-api-1-put.html http://www.yuanjiaocheng.net/we ...
- DDD领域驱动设计 - 设计文档模板
设计文档模板: 系统背景和定位 业务需求描述 系统用例图 关键业务流程图 领域语言整理,主要是整理领域中的各种术语的定义,名词解释 领域划分(分析出子域.核心域.支撑域) 每个子域的领域模型设计(实体 ...
- 使用rowid抽取数据方法以及大数据量游标卡住的应对
平时工作的时候,经常会遇到这种事情,从一个大表A中,抽取字段a在一个相对较小B的表的数据,比如,从一个详单表中,抽取几万个用户号码的话单出来.这种时候,一般来说, 做关联查询: create tabl ...
- kali linux下的arp攻击
这是我第一篇博客,写的不好请谅解 ____________________________(分割线)_______________________________ 在kali linux系统下自带工具 ...
- 如何dos命令打开服务窗口?
1.输入services.msc点击<确定>进入服务窗口.如图: