《C#入门经典》学习笔记(集合、比较和转换).docx_第1页
《C#入门经典》学习笔记(集合、比较和转换).docx_第2页
《C#入门经典》学习笔记(集合、比较和转换).docx_第3页
《C#入门经典》学习笔记(集合、比较和转换).docx_第4页
《C#入门经典》学习笔记(集合、比较和转换).docx_第5页
已阅读5页,还剩11页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

C#入门经典学习笔记(集合、比较和转换)集合C#中的数组是作为System.Array类的实例来执行的,它们是集合类中的一种集合类一般用于处理对象列表,其功能是通过执行System.Collection中的接口实现的集合的功能可以通过接口来实现该接口可以使用基本基本集合类,也可以创建自定义的集合类System.Collections 命名空间有很多接口提供了基本的集合功能:IEnumerable:公开枚举数,该枚举数支持在非泛型集合上进行简单迭代ICollection:定义所有非泛型集合的大小、枚举数和同步方法IList:表示可按照索引单独访问的对象的非泛型集合IDictionary:表示键/值对的非通用集合System.Array类继承了IList,ICollection和IEnumerable但不支持IList的一些高级功能,而且是一个大小固定的项目列表使用集合Systems.Collections中的一个类System.Collections.ArrayList,也执行IList,ICollection和IEnumerable接口,但与数组不同,它是大小可变的使用System.Array类的集合(数组),必须用固定的大小来初始化数组例如:Animal animalArray = new Animal2;使用System.ArrayList类的集合,不需要初始化其大小例如:ArrayList animalArrayList = new ArrayList();这个类还有两个构造函数:1 把现有集合作为参数复制到新实例中2 用一个int参数设置集合的容量,不过实际内容超过容量时会自动增加初始化数组,需要给这个项目赋予初始化了的对象例如:Cow myCow1 = new Cow(Deirdre);animalArray0 = myCow1;animalArray1 = new Chicken(Ken);可以用这两种方式初始化数组对于ArrayList集合,需要用Add()方法添加新项目例如:Cow myCow2 = new Cow(Hayley);animalArrayList.Add(myCow2);animalArrayList.Add(new Chicken(Roy);在添加万项目之后,就可以用与数组相同的语法重写他们例如:animalArrayList1 = 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的方法animalArray0.Feed();但对于类Animal派生类的方法,就不能直接调用,需要强制转换(Chicken)animalArray1).LayEgg();ArrayList集合是System.Object对象的集合,通过多态性赋給Animal对象必须进行数据类型转换例如:(Animal)animalArrayList0).Feed();(Chicken)animalArrayList1).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)animalArrayListiIndex).Feed();定义集合可以从一个类派生自定义的集合推荐使用System.Collections.CollectionBase类CollectionBase类有接口IEnumerable,ICollection,和IListList属性可以通过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() 这个类用于生成Animal类型的集合,可以用foreach访问其成员:Animals animalCollection = new Animals();animalCollection.Add(new Cow(Sarah);foreach (Animal myAnimal in animalCollection)如果要以索引的方式访问项目,就需要使用索引符索引符索引符是一种特殊类型的属性,可以把它添加到类中,提供类似数组的访问最常见的一个用法是对项目执行一个数字索引例如:在Animals集合中添加一个索引符public class Animals : CollectionBase . public Animal thisint animalIndex get return (Animal)ListanimalIndex; set ListanimalIndex = value; this关键字与方括号一起,方括号中是索引参数对List使用一个索引符,而且显示声明了类型,因为IList接口返回的是System.Object对象现在可以用索引的方式访问项目:animalCollection0.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 thisstring animalID get return (Animal)DictionaryanimalID; set DictionaryanimalID = value; 这样添加了Add()方法,Remove()方法和一个通过关键字访问项目的方法其中Dictionary是包含在DictionaryBase实例中的元素的列表DictionaryBase集合和CollectionBase集合在foreach的工作方式不同,DictionaryBase提供的是DictionaryEntry结构,需要通过Value成员获取对象本身例如:CollectionBase集合:foreach (Animal myAnimal in animalCollection) myAnimal.Feed();DictionaryBase集合:foreach (DictionaryEntry myEntry in animalCollection) (Animal)myEntry.Value).Feed();迭代器通过IEnumerable接口,可以使用foreach循环获取对象foreach循环,迭代collectionObject的过程:1 调用Collection的GetEnumerator()方法返回一个IEnumerator引用 该方法也可以通过IEnumerable接口的实现代码获得2 调用IEnumerator接口的MoveNext()方法,将枚举数推进到集合的下一个元素3 如果MoveNext()方法返回true,使用IEnumerator接口的Current属性获取对象的引用,用于foreach循环4 重复前两个步骤,直至MoveNext()返回false时,循环停止迭代器是一个按顺序提供要在foreach循环中使用的所有值的代码块一般这个代码块是一个方法,也可以使用属性访问器和其他代码块作为迭代器代码块的返回值可能是IEnumerable或IEnumerator接口类型:1 如果要迭代一个类,可使用方法IEnumerator(),其返回类型是IEnumerator2 如果要迭代一个类成员,则使用IEnumerable在迭代器块中,使用yield关键字选择要在foreach循环中使用的值语法:yield return value;例如:public static IEnumerable SimpleList() yield return string 1; yield return string 2; yield return string 3;public static void Main(string args) foreach (string item in SimpleList() Console.WriteLine(item); Console.ReadKey();这里SimpleList就是迭代器块,是一个方法,使用IEnumerable返回类型可以从yield语句中返回任意类型可以中断信息返回foreach循环过程语法:yield break;迭代器和集合迭代器可以用于迭代储存在目录类型的集合中的对象例如:public new IEnumerator GetEnumerator() foreach (object animal in Dictionary.Values) yield return (Animal)animal;迭代集合中的对象:foreach (Animal myAnimal in animalCollection)深度复制使用System.Object.MemberwiseClone()方法可以进行阴影复制对于值类型成员,没什么问题但对于引用类型成员,新对象和源对象的成员将指向同一个引用对象例如:public class Content public int Val;public class Cloner public Content MyContent = new Content(); public Cloner(int newVal) MyContent.Val = newVal; public object GetCopy() return MemberwiseClone(); 执行:Cloner mySource = new Cloner(5);Cloner myTarget = (Cloner)mySource.GetCopy();int iVal1 = myTarget.MyContent.Val;mySource.MyContent.Val = 2;int iVal2 = myTarget.MyContent.Val;结果:iVal1是5,iVal2是2但有时候需要的是分别引用各自的对象,使用深度复制就可以解决标准方式是添加一个ICloneable接口,该接口有一个Clone()方法该方法不带参数,返回一个对象类型例如:public class Content public int Val;public class Cloner : ICloneable public Content MyContent = new Content(); public int iVal = 0; public Cloner(int newVal) MyContent.Val = newVal; public object Clone() Cloner clonedCloner = new Cloner(MyContent.Val); clonedCloner.iVal = iVal; return clonedCloner; 通过Cloner对象的Val字段创建一个相同的Cloner对象如果有值成员需要复制,那必须给新对象添加上这个成员这样就能复制一个与源对象相同而互相独立的新对象用GetCopy换成Clone,执行相同的程序,结果:iVal1是5,iVal2是5比较类型比较 比较对象时,需要先知道对象的类型,可以使用GetType()方法配合typeof()运算符一起使用,就可以确定对象的类型if (myObj.GetType() = typeof(MyComplexClass) / myObj is an instance of the class MyComplexClass.封箱和拆箱处理值类型时后台的操作:封箱(boxing)是把值类型转换为System.Object类型或由值类型实现的接口类型拆箱(unboxing)是相反的过程例如:结构类型:struct MyStruct public int Val;把类型结构放在object类型变量中封箱:MyStruct valType1 = new MyStruct();valType1.Val = 5;object refType = valType1;这里创建了一个MyStruct类型的valType1,给成员赋值后封箱到对象refType中这种方式的封装,将包含值类型的一个副本的引用,而不是源值的引用验证:valType1.Val = 6;MyStruct valType2 = (MyStruct)refType;结果valType2.Val是5而不是6如果对个引用类型进行封装,将包含源值的引用例如:class MyStruct public int Val;执行相同的操作,得到valType2.Val的值是6可以把值类型封箱到一个接口类型中:interface IMyInterfacestruct MyStruct : IMyInterface public int Val;把结构封箱到IMyInterface类型中:MyStruct valType1 = new MyStruct();IMyInterface refType = valType1;拆箱:MyStruct ValType2 = (MyStruct)refType;封箱是在没有用户干涉的情况下进行的拆箱一个值需要进行显式转换(封箱是隐式的转换)访问值类型的内容前,必须进行拆箱is运算符is运算符可以检查对象是否是给定的类型,或者是否可以转换为给定的类型语法: is 1 如果是一个类类型,也是该类型,或继承了该类型,或封箱到该类型中,则返回true2 如果是一个接口类型,也是该类型,或是实现该接口的类型,则返回true3 如果是一个值类型,也是该类型,或封箱到该类型中,则返回true值比较运算符重载要重载运算符,可给类添加运算符类型成员(必须是static)例如:重载+运算符:Code运算符重载与标准静态方法声明类似,但它使用关键字operator和运算符本身使用:Code结果op3.val的值是9注意:如果混合了类型,操作数数序必须与运算符重载参数顺序相同可以重载的运算符:一元运算符:+,-,!,+,-,true,false二元运算符:+,-,*,/,%,&,|,比较运算符:=,!=,=注意:如果重载true或false运算符,可以在布尔表达式中使用类,例如if (op1) 运算符如 必须成对重载,但可以使用其他运算符来减少代码例如:Code同时适用于=和!=,常常需要重写Object.Equals()和Object.GetHashCode()CodeIComparable和IComparer接口IComparable和IComparer接口是比较对象的标准方式区别:IComparable在要比较的对象的类中实现,可以比较该对象和另一个对象IComparer在一个单独的类中实现,可以比较任意两个对象.Net Framework 在类Comparer上提供了IComparer接口的默认实现方式,类Comparer位于System.Collections命名空间中,可以对简单类型以及支持IComparable接口的任意类型进行特定文化的比较publicclassSamplesComparerpublicstaticvoidMain()Stringstr1=llegar;Stringstr2=lugar;Console.WriteLine(Comparing0and1,str1,str2);/UsestheDefaultInvariantComparer.Console.WriteLine(InvariantComparer:0,Comparer.DefaultInvariant.Compare(str1,str2);/UsestheComparerbasedontheculturees-ES(Spanish-Spain,internationalsort).ComparermyCompIntl=newComparer(newCultureInfo(es-ES,false);Console.WriteLine(InternationalSort:0,myCompIntl.Compare(str1,str2)一般使用IComparable给出类的默认比较代码,使用其他类给出非默认的比较代码IComparable提供一个CompareTo()方法比较两个对象,并返回一个int值例如:classPerson:IComparablepublicstringName;publicintAge;publicPerson(stringname,intage)Name=name;Age=age;publicintCompareTo(objectobj)if(objisPerson)PersonotherPerson=objasPerson;returnthis.Age-otherPerson.Age;elsethrownewArgumentException(ObjecttocomparetoisnotaPersonobject.);主程序代码classProgramstaticvoidMain(stringargs)Personperson1=newPerson(Jim,30);Personperson2=newPerson(Bob,25);if(person1.CompareTo(person2)=0)Console.WriteLine(Sameage);elseif(person1.CompareTo(person2)0)Console.WriteLine(person1isOlder);elseConsole.WriteLine(person1isYounger);IComparer提供一个Compare()方法,接受两个对象返回一个整型结果例如:publicclassPersonComparer:IComparerpublicstaticIComparerDefault=newPersonComparer();publicintCompare(objectx,objecty)if(xisPerson&yisPerson)returnComparer.Default.Compare(Person)x).Age,(Person)y).Age);elsethrownewArgumentException(OneorbothobjectstocomparearenotPersonobjects.);主程序:classProgramstaticvoidMain(stringargs)Personperson1=newPerson(Jim,30);Personperson2=newPerson(Bob,25);if(PersonComparer.Default.Compare(person1,person2)=0)Console.WriteLine(Sameage);elseif(PersonComparer.Default.Compare(person1,person2)0)Console.WriteLin

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论