第11章 集合、比较和转换(C#入门经典第6版)
1、集合
数据有一定的限制,最不能忍受的是一旦创建,数组的大小就固定,不能再添加。而集合则包含了数组所具有的功能,且可以任意添加/删减元素项,还有一些其他 功能。
集合的功能主要通过接口来实现,接口包含在System.Collections命名空间中。
主要有:
- IEnumerable 可以迭代集合中的元素项
- ICollection(继承于IEnumerable)可以获得集合中元素项的个数,并能把元素项复制到一个简单的数组类型中。
- IList(继承于IEnumerable和ICollection)提供了集合的元素项列表,允许访问这些项,并提供其他一些与元素项列表相关的基本功能。
- IDictionary(继承于IEnumerable和ICollection)类似于IList,但提供了可通过健值访问的元素项列表。
(1)System.Array类与System.Collections.ArrayList类
- class Program
- {
- static void Main(string[] args)
- {
- Console.WriteLine("Create an Array type collection of Animal " +
- "objects and use it:");
- Animal[] animalArray = new Animal[];
- Cow myCow1 = new Cow("Deirdre");
- animalArray[] = myCow1;
- animalArray[] = new Chicken("Ken");
- foreach (Animal myAnimal in animalArray)
- {
- Console.WriteLine("New {0} object added to Array collection, " +
- "Name = {1}", myAnimal.ToString(), myAnimal.Name);
- }
- Console.WriteLine("Array collection contains {0} objects.", animalArray.Length);
- animalArray[].Feed();
- ((Chicken)animalArray[]).LayEgg();
- Console.WriteLine();
- Console.WriteLine("Create an ArrayList type collection of Animal " +
- "objects and use it:");
- ArrayList animalArrayList = new ArrayList();
- Cow myCow2 = new Cow("Hayley");
- animalArrayList.Add(myCow2);
- animalArrayList.Add(new Chicken("Roy"));
- foreach (Animal myAnimal in animalArrayList)
- {
- Console.WriteLine("New {0} object added to ArrayList collection," +
- " Name = {1}", myAnimal.ToString(), myAnimal.Name);
- }
- Console.WriteLine("ArrayList collection contains {0} objects.", animalArrayList.Count);
- ((Animal)animalArrayList[]).Feed();
- ((Chicken)animalArrayList[]).LayEgg();
- Console.WriteLine();
- Console.WriteLine("Additional manipulation of ArrayList:");
- animalArrayList.RemoveAt();
- ((Animal)animalArrayList[]).Feed();
- animalArrayList.AddRange(animalArray);
- ((Chicken)animalArrayList[]).LayEgg();
- Console.WriteLine("The animal called {0} is at index {1}.",
- myCow1.Name, animalArrayList.IndexOf(myCow1));
- myCow1.Name = "Janice";
- Console.WriteLine("The animal is now called {0}.",
- ((Animal)animalArrayList[]).Name);
- Console.ReadKey();
- }
- }
System.Array类只能在初始化时固定数组大小,如:
Animal[] animalArray = new Animal[2];
而System.Collections.ArrayList类则是:
ArrayList animalArrayList = new ArrayList();//可以设置容量 ,但当超过时会自动增加一倍。
简单数组Array中是强类型的,本例中是Animal类型,而ArrayList中则是System.Object。
System.Array类和ArrayList都实现了IEnumerable接口,因此可以在foreach中迭代。
(2)定义集合---创建自己的强类型化集合
一般情况是从一个类中派生自己的集合,例如System.Collections.CollectionBase类,这个抽象类提供了集合类的大量的实现代码,包含了IEnumerable、ICollection、Ilist接口。
CollectionBase类提供了两个受保护的属性,可以访问存储对象本身。List可以通过IList接口访问项,而InnerList则可用于存储项的ArrayList对象。
- public class Animals:CollectionBase
- {
- public void Add(Animal newAnimal)
- {
- List.Add(newAnimal);
- }
- public void Remove(Animal oldAnimal)
- {
- List.Remove(oldAnimal);
- }
- public Animals()
- {
- }
- }
(3)索引符
上面定义的集合Animals是不能如animalCollection[0].Feed()这样按照索引来访问元素项的,必须使用索引符。
索引符其实是一种特殊类型的属性,可添加在类中,提供类似于数组的访问。
- public Animal this[int animalIndex]//this关键字和后边的方括号中的参数一起使用,如MyAnimals[0]。
- {
- get { return (Animal)List[animalIndex]; }
- set { List[animalIndex] = value; }
- }
小结:通过使用CollectionBase创建自己的强类型化集合集中了System.Array类的强类型化和System.Collections.ArrayList的多种项列表操作方法的优点,比较方便。但是内部还是发生了类型转换。
(4)键控集合和IDictionary
类似于IList接口通过数字索引访问项列表,IDictionary接口通过健值进行索引。同样,也有一个基类实现了IDictionary接口,DictionaryBase。
- public class Animals:DictionaryBase
- {
- public void Add(string newID,Animal newAnimal)
- {
- Dictionary.Add(newID, newAnimal);
- }
- public void Remove(string animalID)
- {
- Dictionary.Remove(animalID);
- }
- public Animals()
- { }
- public Animal this[string animalID]
- {
- get { return (Animal)Dictionary[animalID]; }
- set { Dictionary[animalID] = value; }
- }
- }
但是基于DictionaryBase的集合和基于CollectionBase的集合之间还有一个区别是foreach的工作方式稍有区别。基于CollectionBase的集合可以从集合中直接提取Animal对象,而使用foreach和DictionaryBase的集合则需要提供DictionaryEntry结构才能得到类似的效果。
- foreach (DictionaryEntry myEntry in animalCollection)
- {
- Console.WriteLine("New {0} object added to custom collection, " +
- "Name = {1}", myEntry.Value.ToString(), ((Animal)myEntry.Value).Name);
- }
(5) 迭代器
迭代器的定义是,它是一个代码块,按顺序提供了要在foreach循环中使用的所有值。迭代器代码块的返回类型有两种,IEnumerable和IEnumerator。
如果要迭代一个类,可使用方法GetEnumerator(),其返回类型是IEnumerator。
如果要迭代一个类成员,则使用IEnumerable。
这里要使用yield关键字,但书上没有详细介绍。
(6)深度复制
所谓深度复制和浅度复制,在值类型上感觉是没有区别的,都是复制一个值,而在引用类型上,浅度复制是复制对象的一个相同的引用,副本改变后则源也要改变。但是深度复制则不同,其复制对象的内容(包括字段等)而引用不同,副本发生变化时,源则不变。
2、比较
(1)类型比较
a. 封箱与拆箱
封箱是把值类型转换为System.Object类型或者转换为由值类型实现的接口类型。包含值类型变量的一个副本的引用。
拆箱是相反的过程。
封箱是在没有用户干涉的情况下进行的(即不需要编写任何代码),但是拆箱一个值需要进行显式转换,即需要类型转换。
b. is运算符
is运算符并不是用来说明对象是某种类型,而是用来检查对象是不是给定类型,或者是否可以转换为给定类型,如果是,就返回true。
<operand> is <type>
- 如果<type>是一个类类型,而<operand>也是该类型,或者它继承了该类型,或者它可以封装到该类型中,则结果为true。
- 如果<type>是一个接口类型,而<operand>也是该类型,或者它是实现该接口的类型,则结果为true。
- 如果<type>是一个值类型,而<operand>也是该类型,或者它可以拆箱到该类型中,则结果为true。
(2)值比较
a. 运算符重载
要在类中重载运算符,必须给类添加运算符类型成员(使用operator关键字和运算符本身)且必须是static。
b. 使用IComparable和IComparer接口,该种方式广泛用于集合类中。
- IComparable在要比较的对象的类中实现,可以比较该对象和另一个对象
- IComparer在一个单独的类中实现,可以比较任意两个对象
一般使用IComparable给出类的默认比较代码,使用其他类给出非默认的比较代码。IComparable提供了一个方法CompareTo(),这个方法接受一个对象。IComparer也提供了一个Compare()方法。
最后,.Net Framework在类Comparer上提供了IComparer接口的默认实现方式,类Comparer位于System.Collections命名空间中,可以对简单类型以及支持IComparable接口的任意类型进行特定文化的比较。
3、转换
(1)重载转换运算符
在代码中,使用关键字implicit和explicit来指定转换
- public class ConvClass1
- {
- public int val;
- public static implicit operator ConvClass2(ConvClass1 op1)
- {
- ConvClass2 returnVal = new ConvClass2();
- returnVal.val = op1.val;
- return returnVal;
- }
- }
- public class ConvClass2
- {
- public double val;
- public static explicit operator ConvClass1(ConvClass2 op1)
- {
- ConvClass1 returnVal = new ConvClass1();
- returnVal.val = (int)(op1.val);
- return returnVal;
- }
- }
(2) as运算符
使用下面的语法,把一种类型转换为指定的引用类型。
<operand> as <type>
- <operand>的类型是<type>类型
- <operand>可以隐式转换为<type>类型
- <operand>可以封箱到<type>类型中
如果不能从<operand>转换为<type>,则表达式的结果为null。
第11章 集合、比较和转换(C#入门经典第6版)的更多相关文章
- UNP第11章——名字与地址转换
1.域名系统 程序中只使用主机名和服务名的好处是,如果IP或端口变化,只需要改变映射关系,不需要重新编译程序. 1.1 资源记录 DNS的条目为资源记录,有用的项如下: A IPv4地址 AAAA I ...
- C#入门经典第11章集合-1
- 【机器学习实战】第11章 使用 Apriori 算法进行关联分析
第 11 章 使用 Apriori 算法进行关联分析 关联分析 关联分析是一种在大规模数据集中寻找有趣关系的任务. 这些关系可以有两种形式: 频繁项集(frequent item sets): 经常出 ...
- Java核心技术卷一基础知识-第11章-异常、断言、日志和调试-读书笔记
第11章 异常.断言.日志和调试 本章内容: * 处理错误 * 捕获异常 * 使用异常机制的技巧 * 使用断言 * 日志 * 调试技巧 * GUI程序排错技巧 * 使用调试器 11.1 处理错误 如果 ...
- 第19章 集合框架(3)-Map接口
第19章 集合框架(3)-Map接口 1.Map接口概述 Map是一种映射关系,那么什么是映射关系呢? 映射的数学解释 设A,B是两个非空集合,如果存在一个法则,使得对A中的每一个元素a,按法则f,在 ...
- java JDK8 学习笔记——第11章 线程和并行API
第11章 线程与并行API 11.1 线程 11.1.1 线程 在java中,如果想在main()以外独立设计流程,可以撰写类操作java.lang.Runnable接口,流程的进入点是操作在run( ...
- Linux就这个范儿 第11章 独霸网络的蜘蛛神功
Linux就这个范儿 第11章 独霸网络的蜘蛛神功 第11章 应用层 (Application):网络服务与最终用户的一个接口.协议有:HTTP FTP TFTP SMTP SNMP DNS表示层 ...
- 翻译连载 | 第 11 章:融会贯通 -《JavaScript轻量级函数式编程》 |《你不知道的JS》姊妹篇
原文地址:Functional-Light-JS 原文作者:Kyle Simpson-<You-Dont-Know-JS>作者 关于译者:这是一个流淌着沪江血液的纯粹工程:认真,是 HTM ...
- Java核心技术卷一基础技术-第13章-集合-读书笔记
第13章 集合 本章内容: * 集合接口 * 具体的集合 * 集合框架 * 算法 * 遗留的集合 13.1 集合接口 Enumeration接口提供了一种用于访问任意容器中各个元素的抽象机制. 13. ...
随机推荐
- HTTP状态码:400\500 错误代码
一些常见的状态码为: 200 - 服务器成功返回网页404 - 请求的网页不存在503 - 服务不可用详细分解: 1xx(临时响应)表示临时响应并需要请求者继续执行操作的状态代码. 代码 说明100 ...
- 用命令行批处理bat,设置代理服务器、DNS、网关、WINS等
http://hi.baidu.com/83050158/blog/item/50cbd63f9da79ccb7d1e711b.html 将下面代码复制到记事本,另存为NetSet.bat,修改相应i ...
- mysql 查询copy to tmp table造成堵塞
show full PROCESSLIST; show VARIABLES like 'tmp_table_size' set GLOBAL tmp_table_size=629145600; SHO ...
- 测试RegExp对象的属性
//测试RegExp对象的属性function testRegExpProperty(){ var regexp = /abc/; //regexp.ignoreCase = true; //无效 c ...
- CSS选择器解析
通配符选择器 Universal Selector * { -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizin ...
- 【创建型】Singleton模式
单例模式可以说是所有23种设计模式中最为简单的一个,没有之一.其主要思想就是保证整个应用环境中,最多只会有一个对象的实例.类关系图参考如下: 在c++中,单例模式的实现,较为常用的实现方式一般为: n ...
- 文成小盆友python-num15 - JavaScript基础
一.JavaScript简介 JavaScript一种直译式脚本语言,是一种动态类型.弱类型.基于原型的语言,内置支持类型.它的解释器被称为JavaScript引擎,为浏览器的一部分,广泛用于客户端的 ...
- angularJs项目实战!04:angularjs的性能问题
上一篇文章中我花了很多口舌去介绍angularjs是一个中型框架,面对大型应用时少不了第三方类库的配合.而我的核心议题是:如何以angularjs的思路使用其他类库,这里jquery是最好的例子了,谁 ...
- file_get_content、fsockopen和curl之间的优缺点
file_get_content 优点:在抓取单个文件上,效率很高,返回没有头信息的文件. 缺点:在抓取远程文件时,和fopen一样容易出错.在抓取多个跨域文件时,未对DNS进行缓存,所以效率上不不高 ...
- PHP and java
问题补充: 为什么不选用优秀的ASP.NET,京东做的不是很成功嘛?-----------------------------------------------------------------首 ...