---------------集合、比较和转换---------------

C#中的数组是作为System.Array类的实例实现的,它们是集合类(Collection Classes)中的一种类型。

集合类一般用于处理对象列表,大多通过实现System.Collections名称空间中的接口而获得的

System.Collections名称空间中的几个接口提供了基本的集合功能:

 1)IEnumerable可以迭代集合中的项。

 2)ICollection(继承于IEnumerable)可以获取集合中的项的个数,并能把项复制到一个简单的数组类型中。

 3)IList(继承于IEnumerable和ICollection)提供了集合的项列表,允许访问这些项,并提供其他一些与项列表相关的基本功能

 4)IDictionary(继承于IEnumerable和ICollection)类似于IList,但提供了可通过键值(而不是索引)访问的项列表。

System.Array类实现了IList、ICollection和IEnumerable,但不支持IList的一些更高级的功能,它表示大小固定的项列表。

数组初始化需要固定大小,ArrayList集合则不用

 Animal[] animalArray = new Animal[2];

 ArrayList animalArrayList = new ArrayList();

这个类还有两个构造函数:

 1、把现有集合作为参数复制到新实例中

 2、用一个int参数设置集合的容量,不过实际内容超过容量时会自动增加

初始化数组,需要给这个项目赋予初始化了的对象 例如:

 Cow myCow1 = new Cow("Deirdre");
animalArray[] = myCow1;
animalArray[] = new Chicken("Ken");

可以用这两种方式初始化数组

对于ArrayList集合,需要用Add()方法添加新项目
例如:

 Cow myCow2 = new Cow("Hayley");
animalArrayList.Add(myCow2);
animalArrayList.Add(new Chicken("Roy"));

在添加完项目之后,就可以用与数组相同的语法重写他们
例如:

animalArrayList[] = new Chicken("Roy2")

Array数组和ArrayList集合都支持foreach结构来迭代
例如:

 foreach (Animal myAnimal in animalArray)
{
}
foreach (Animal myAnimal in animalArrayList)
{
}

Array数组使用Length属性获取项目的个数
例如:

int animalCount = animalArray.Length; 

ArrayList集合使用Count属性获取项目的个数

int animalCount2 = animalArrayList.Count; 

Array数组是强类型化的,可以直接使用数组的类型来存储项目
即可以直接访问项目的属性和方法
例如:
对于类型是Animal的数组,Feed()是类Animal的方法

animalArray[].Feed();

但对于类Animal派生类的方法,就不能直接调用,需要强制转换

((Chicken)animalArray[]).LayEgg(); 

使用Remove()和RemoveAt()方法删除项目
Remove  从 ArrayList 中移除特定对象的第一个匹配项(参数为特定对象)
RemoveAt 移除 ArrayList 的指定索引处的元素(参数为索引值) 删除项目后,会使其他项目在数组中移动一个位置
使用AddRange()和InsertRange()方法可以一次添加多个项目
AddRange 将 ICollection 的元素添加到 ArrayList 的末尾
InsertRange 将集合中的某个元素插入 ArrayList 的指定索引处。 例如:

animalArrayList.AddRange(animalArray); 

使用IndexOf()方法获取指定项目的索引值
IndexOf 返回 ArrayList 或它的一部分中某个值的第一个匹配项的从零开始的索引。
可以通过索引值直接访问选项
例如:

int iIndex =  animalArrayList.IndexOf(myCow1);
((Animal)animalArrayList[iIndex]).Feed();

定义集合
从System.Collections.CollectionBase这个抽象类中派生自己的集合,此类提供了集合类的许多实现方法
CollectionBase类有IEumerable、ICollection和IList接口
CollectionBase提供了两个受保护的属性,可访问存储的对象本身,分别为List和InnerList,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(){}
}

使用ArrayList实现代码处理对象

 Animals animalCollection = new Animals();
animalCollection.Add(new Cow("Cow1"));
foreach(Animal myAnimal in animalCollection)
{
Console.WriteLine("{0} {1}",myAnimal.ToString(),myAnimal.Name);
}

不能用animalCollection[0].Feed();因为没有索引符
索引符可添加到类中,使之提供类似于数组的访问,例如:

 public class Animals:CollectionBase
{
public Animal this[int animalIndex]
{
get{return (Animal)List[animalIndex];}
set{List[animalIndex] = value;}
}
}

如此即可使用上面无法使用的animalCollection[0].Feed();

关键字值集合和IDictionary

与索引的集合一样,可使用一个基类简化IDictionary接口的实现,即DictionaryBase,它也实现IEnumerable和ICollection

关键字值集合举例:

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的成员Dictionary,此成员是一个IDictionary接口
使用foreach和DictionaryBase派生类可以提供DictionaryEntry结构,例如:

foreach(DictionaryEntry myEntry in animalCollection)
{
Console.WriteLine("{0} {1}",myEntry.Value.ToString(),((Animal)myEntry.Value).Name);
}

如果要直接通过foreach提取Animal对象,最简单的方式是实现一个迭代器

迭代器
IEnumerable接口负责使用foreach循环,在foreach循环中,迭代集合collectionObject的过程如下:
1)调用collectionObject.GetEnumerator(),返回一个IEnumerator引用,此方法可通过IEnumerable接口的实现代码来获得,但这是可选的。
2)调用所返回的IEnumerator接口的MoveNext()方法。
3)如果MoveNext()方法返回true,就是用IEnumerator接口的Current属性获取对象的一个引用,用于foreach循环。
4)重复前面两步,知道MoveNext()方法返回false为止,此时循环停止
 所以,为了在类中进行这些操作,必须重写几个方法,跟踪索引,维护Current属性,以及执行其他一些操作。
 一个较为简单的替代方法是使用迭代器,它是一个代码块,按顺序提供了要在foreach循环中使用的所有值。一般情况下,这个代码块是一个方法,但也可以使用属性访问器和其他代码块作为迭代器。
1)如果要迭代一个类,可使用方法GetEnumerator(),其返回类型是IEnmerator
 2)如果要迭代一个类成员,例如一个方法,则使用IEnumerable
在迭代器块中,使用yield关键字选择要在foreach循环中使用的值,以下举例:

public static IEnumerable SimpleList()
{
yield return "string 1";
yield return "string 2";
yield return "string 3";
}
public static void test()
{
foreach(string item in SimpleList())
{
Console.WriteLine(item);
}
Console.ReadKey();
}

SimpleList()就是迭代器块,迭代器块内的返回类型必须一致,否则出现错误类型转换异常。
在遇到迭代器中yield break;这个语句时,迭代器处理立即中断。

浅复制与深复制
 浅显的来说,浅复制类似于引用类型,深复制类似于值类型。
 浅复制是指源对象和复制对象共用一份实体,仅仅是引用的变量不同,相当于复制了一个快捷方式。
 深复制是指源对象和复制对象相互独立,改变其中一个对象不会对另一个造成印象,相当于复制了文件本身。
MemberwiseClone 方法创建一个浅表副本,方法是创建一个新对象,然后将当前对象的非静态字段复制到该新对象。如果字段是值类型的,则对该字段执行逐位复制。如果字段是引用类型,则复制引用但不复制引用的对象;因此,原始对象及其复本引用同一对象。深复制,即实现ICloneable接口.ICloneable可用于深复制和浅复制。
 举例说明:

public class Content
{
public int Val;
}

浅复制(shallow copy)

public class ShallowCopy
{
public Content myContent = new Content();
public ShallowCopy(int newVal)
{
myContent.Val = newVal;
}
public object GetCopy()
{
return MemberwiseClone();
}
}

深复制(deep copy)

public class DeepCopy:ICloneable
{
public Content myContent = new Content();
public DeepCopy(int newVal)
{
myContent.Val = newVal;
}
public object Clone()
{
DeepCopy Cloner = new DeepCopy(myContent.Val);
return Cloner;
}
}

C#入门经典(第五版)学习笔记(四)的更多相关文章

  1. Docker技术入门与实战 第二版-学习笔记-10-Docker Machine 项目-2-driver

    1>使用的driver 1〉generic 使用带有SSH的现有VM/主机创建机器. 如果你使用的是机器不直接支持的provider,或者希望导入现有主机以允许Docker Machine进行管 ...

  2. Docker技术入门与实战 第二版-学习笔记-8-网络功能network-3-容器访问控制和自定义网桥

    1)容器访问控制 容器的访问控制,主要通过 Linux 上的 iptables防火墙来进行管理和实现. iptables是 Linux 上默认的防火墙软件,在大部分发行版中都自带. 容器访问外部网络 ...

  3. 《c#入门经典第五版》简介及pdf电子书网盘下载地址(收藏)

    <C#入门经典(第5版)>全面讲解C# 2010和.net架构编程知识,为您编写卓越C# 2010程序奠定坚实基础.C#入门经典系列是屡获殊荣的C#名著和超级畅销书.最新版的<C#入 ...

  4. Docker技术入门与实战 第二版-学习笔记-10-Docker Machine 项目-1-cli

    Docker Machine 是 Docker 官方编排(Orchestration)项目之一,负责在多种平台上快速安装 Docker 环境 Docker Machine是一种工具,它允许你在虚拟主机 ...

  5. Docker技术入门与实战 第二版-学习笔记-5-容器-命令及限制内存与cpu资源

    1.启动容器 启动容器有两种方式: 基于镜像新建一个容器并启动 将在终止状态(stopped)的容器重新启动 1)新建并启动——docker run 比如在启动ubuntu:14.04容器,并输出“H ...

  6. C++Primer第五版学习笔记

    <C++ Primer>Learning Note 程序实例下载地址:http://www.informit.com/title/0321714113 第一章            开始 ...

  7. Docker技术入门与实战 第二版-学习笔记-9-Docker Compose 项目-1-举例说明

    Docker Compose 是 Docker 官方编排(Orchestration)项目之一,负责快速在集群中部署分布式应用 Compose 通过一个配置文件来管理多个Docker容器,在配置文件中 ...

  8. Docker技术入门与实战 第二版-学习笔记-6-仓库

    仓库(Repository)是集中存放镜像的地方 一个容易混淆的概念是注册服务器(Registry). 实际上注册服务器是管理仓库的具体服务器,每个服务器上可以有多个仓库,而每个仓库下面有多个镜像. ...

  9. Docker技术入门与实战 第二版-学习笔记-7-数据管理(volume)

    Docker 数据管理 为什么要进行数据管理呢?因为当我们在使用container时,可能会在里面创建一些数据或文件,但是当我们停掉或删除这个容器时,这些数据或文件也会同样被删除,这是我们并不想看见的 ...

  10. Docker技术入门与实战 第二版-学习笔记-2-镜像构建

    3.利用 commit 理解镜像构成 在之前的例子中,我们所使用的都是来自于 Docker Hub 的镜像. 直接使用这些镜像是可以满足一定的需求,而当这些镜像无法直接满足需求时,我们就需要定制这些镜 ...

随机推荐

  1. 14.5.5 Deadlocks in InnoDB

    14.5.5 Deadlocks in InnoDB 14.5.5.1 An InnoDB Deadlock Example 14.5.5.2 Deadlock Detection and Rollb ...

  2. 【转】linux 中dd命令使用详解

    原文网址:http://xiaozhuang.blog.51cto.com/4396589/850657 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究 ...

  3. 登录MD5加盐处理

    一:解决方案资源管理器截图: 二:operatorDAL.cs代码 using System; using System.Collections.Generic; using System.Linq; ...

  4. 游戏开发设计模式之状态模式 & 有限状态机 & c#委托事件(unity3d 示例实现)

    命令模式:游戏开发设计模式之命令模式(unity3d 示例实现) 对象池模式:游戏开发设计模式之对象池模式(unity3d 示例实现) 原型模式:游戏开发设计模式之原型模式 & unity3d ...

  5. 【转】Markus Persson:Minecraft 游戏背后的奇才

    转自酷勤网 Markus Persson是沙盒游戏Minecraft的开发者,在游戏中以Notch的名字为众多玩家所知,是游戏界绝对的巨星.美国<滚石>杂志的专栏作家David Peisn ...

  6. JavaScript高级程序设计5.pdf

    队列方法访问规则是FIFO(First-In-First-Out,先进先出),数组方法shift()能够移除数组中第一个项并返回该项,同时将数组长度减1,结合使用shift()和push(),可以像队 ...

  7. 在Openstack H版部署Nova Cell 时 ,终端输入nova service-list 和 nova host-list 命令将报错

    关于Cell的基本介绍,可以参考贤哥的一篇文章: [OpenStack]G版中关于Nova的Cell  http://blog.csdn.net/lynn_kong/article/details/8 ...

  8. LaTeX手动安装宏包(package)以及生成帮助文档的整套流程

    注意:版权所有,转载请注明出处. 我使用的是ctex套装,本来已经自带了许多package,但是有时候还是需要使用一些没有预装的宏包,这时就需要自己安装package了.下载package可以从CTA ...

  9. Div 3 - SGU 105(找规律)

    分析:很容易知道序列1,2,3, 4,5, 6......与3的关系就是1,2, 0,1, 2,0,......如果是在一个数后面添加一个数就变成了这种序列1, 0, 0, 1, 0, 0, 1, 0 ...

  10. 回某位朋友问题备受phpcgi.exe煎熬现在cpu跑满(解决方案)

    (本文原创,但是cgi参数参考一个大神写的针对小服务器的,希望大家积极投票哦) 下面是对php-cgi.ext过多引起服务器cup%的解决方法,希望对大家有帮助;大多数情况是发生在第四项上;   解决 ...