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版)的更多相关文章

  1. UNP第11章——名字与地址转换

    1.域名系统 程序中只使用主机名和服务名的好处是,如果IP或端口变化,只需要改变映射关系,不需要重新编译程序. 1.1 资源记录 DNS的条目为资源记录,有用的项如下: A IPv4地址 AAAA I ...

  2. C#入门经典第11章集合-1

  3. 【机器学习实战】第11章 使用 Apriori 算法进行关联分析

    第 11 章 使用 Apriori 算法进行关联分析 关联分析 关联分析是一种在大规模数据集中寻找有趣关系的任务. 这些关系可以有两种形式: 频繁项集(frequent item sets): 经常出 ...

  4. Java核心技术卷一基础知识-第11章-异常、断言、日志和调试-读书笔记

    第11章 异常.断言.日志和调试 本章内容: * 处理错误 * 捕获异常 * 使用异常机制的技巧 * 使用断言 * 日志 * 调试技巧 * GUI程序排错技巧 * 使用调试器 11.1 处理错误 如果 ...

  5. 第19章 集合框架(3)-Map接口

    第19章 集合框架(3)-Map接口 1.Map接口概述 Map是一种映射关系,那么什么是映射关系呢? 映射的数学解释 设A,B是两个非空集合,如果存在一个法则,使得对A中的每一个元素a,按法则f,在 ...

  6. java JDK8 学习笔记——第11章 线程和并行API

    第11章 线程与并行API 11.1 线程 11.1.1 线程 在java中,如果想在main()以外独立设计流程,可以撰写类操作java.lang.Runnable接口,流程的进入点是操作在run( ...

  7. Linux就这个范儿 第11章 独霸网络的蜘蛛神功

    Linux就这个范儿 第11章  独霸网络的蜘蛛神功  第11章 应用层 (Application):网络服务与最终用户的一个接口.协议有:HTTP FTP TFTP SMTP SNMP DNS表示层 ...

  8. 翻译连载 | 第 11 章:融会贯通 -《JavaScript轻量级函数式编程》 |《你不知道的JS》姊妹篇

    原文地址:Functional-Light-JS 原文作者:Kyle Simpson-<You-Dont-Know-JS>作者 关于译者:这是一个流淌着沪江血液的纯粹工程:认真,是 HTM ...

  9. Java核心技术卷一基础技术-第13章-集合-读书笔记

    第13章 集合 本章内容: * 集合接口 * 具体的集合 * 集合框架 * 算法 * 遗留的集合 13.1 集合接口 Enumeration接口提供了一种用于访问任意容器中各个元素的抽象机制. 13. ...

随机推荐

  1. 关于 typings install 的使用

    typings 用来管理.d.ts的文件,这种文件是js的一种接口描述,原因是有很多js库并没有typescript的版本. 微软给出一种描述文件,让IDE识别各种js库的代码提示以及类型检查等. 写 ...

  2. JQUERY1.9学习笔记 之基本过滤器(五) 大于选择器

    大于选择器:jQuery( ":gt(index)" )jQuery( ":gt(-index)" ) 例:大于TD5 到TD8 用黄色背景,TD8用红色文字. ...

  3. 离线破win2003域账号密码(更新域数据库不在默认路径的情况)

    国内网站讲了许多方法,很多也讲得不清楚.我把我尝试成功的经验跟大家分享. 方法是按照tim的文章操作,链接如下: http://pauldotcom.com/2011/11/safely-dumpin ...

  4. Go http.HandlerFunc()

    //http.Handler type Handler interface { ServeHTTP(ResponseWriter, *Request) } type HandlerFunc func( ...

  5. MVC通俗演义系列开篇

         最近在读<世界史通俗演义>,发现这本书非常好,比从小上大的历史书好的多.读的开心之余,也不敢跟别人说,怕被说成“通俗”.这跟英文的技术类文章很像.英文中的IT类文章几乎是通俗形象 ...

  6. JQuery 插件 - 弹窗:BlockUI

    JQuery的弹窗插件,网上实在有很多做的比较好的,比如artDialog.layer,甚至EasyUI等等.这些在效果上做的非常好.但我觉得一个小小的弹窗提示,没有必要引用这些(其实是有点大材小用了 ...

  7. 2014-08-05 再次接触VBA

    今天是在吾索实习的第20天.本来今天的计划是完成BBS的界面的设计的,但是中途发生了一些小插曲,经理要求我帮忙用VBA实现EXCEL中表与表之间的动态联编,而且答应了客户明天就要看到成品了.所以只好放 ...

  8. Codeforces Round #300 F - A Heap of Heaps (树状数组 OR 差分)

    F. A Heap of Heaps time limit per test 3 seconds memory limit per test 512 megabytes input standard ...

  9. Misha and Changing Handles

    Description Misha hacked the Codeforces site. Then he decided to let all the users change their hand ...

  10. 关于C/C++函数指针声明的理解

    [前言] 由于最近对函数指针的理解比较模糊,所有又重新学习了一把关于函数指针的知识,参考了很多书籍和网上的文章.现在本人进行一下分享和总结.本文的其实只是整理和总结别人现有的文章,作为备用参考文档. ...