数组要点:简单数组多维数组锯齿数组Array类作为参数的数组枚举元组结构比较同一类型和不同类型的对象如果需要使用同一种类型的多个对象,就可以 使用集合和数组。C#用特殊的记号声明,初始化和使用数组。Array类在后台发挥作用,它为数组中元素的排序和过滤提供了几个方法。使用 枚举器,可以迭代数组中的所有元素。如果需要使用不同类型的多个对象,可以用Tuple类型。简单数组数组声明Type[]arrayN ame;数组初始化ArrayName=newType[4];Type[]arrayName=newType[4];i nt[]arrayName=newint[4]{1,2,3,4}int[]arrayName=newint[]{1 ,2,3,4}int[]arrayName={1,2,3,4}访问数组通过下标访问arrayName[0]=1;int a=arrayName[0];如果使用错误的索引器值(大于数组长度),就会抛出IndexOutOfRangeExceptio n异常。多维数组二维数数组int[,]twodim=newint[3,3]int[,]twodim={{1,2,3} ,{4,5,6},{7,8,9}}锯齿数组Int[][]j=newint[3][];J[0]=newint[2]J[ 1]=newint[3]J[2]=newint[1]Array类所有数组都派生自Array类Rank属性可以获得维数复 制数组(浅表复制)int[]data={1,2,3,4,5,6};int[]data1=(int[])data.Cl one();排序int[]data1=(int[])data.Clone();Array.Sort(data);如果数组元素 是自定义类,必须要实现IComparable接口。因为简单类型实现了这IComparable所以可以直接排序。数组作为参数数组的传 递和返回都是引用类型(Array是一个类类型)数组协变staticvoidDispalyArray(object[]data );可以将一个persion[]传给上面的函数;ArraySegment结构ArraySegment表示数组的一段。i nt[]data={1,2,3,4,5,6};ArraySegmentseg=newArraySegm ent(data,1,2);foreach(variteminseg.Array){}枚举在foreach 语句中使用枚举,可以迭代集合中的元素,且无须知道集中的元素个数。Foreach语句使用了一个枚举器。数组或集合实现了带GetEum erator()的方法的接口。GetEumerator(0返回一个实现IEumerable的接口的枚举。接着foreach就可以用 IEumerable接迭代集合了。foreach语句foreach(varitemindata){Console.Wr iteLine(item);}会被编译器解析为:IEnumeratorenumerator=data.GetEnumera tor();while(enumerator.MoveNext()){varit=enumerator.Curren t;Console.WriteLine(it);}Yieldd语句Yieldreturn会返回信合的一个元素,并移到下一个 元素上。Yieldbreak可以停止迭代publicclassHelloCollection{publicIEnume ratorGetEnumerator(){yieldreturn"hello";yieldretur n"world";}}varc=newHelloCollection();foreach(varitemin c){Console.WriteLine(item);}由于foreach会被编译器解析为IEnumeratorenume rator=c.GetEnumerator();while(enumerator.MoveNext()){varit =enumerator.Current;Console.WriteLine(it);}所以这个类只要有GetEnumerat or()并返回IEnumerator即可使用迭代块,编译器会生成一个yield类型,其中包含一个状态机,如下面所示的代码。Yiel d类型实现IEnumerator和IDisposable接口的属性和方法。在下面的例子中,可以把yield类型看成内部类Enume rator.外部类的GetEnumerator()实例化并返回一个新的yield类型。publicclassHelloColl ection{publicIEnumeratorGetEnumerator(){returnnew Enumerator(0);}publicclassEnumerator:IEnumerator,I Enumerator,IDisposable{privateintstate;publicEnumerator(in tstate){this.state=state;}stringcurrent;publicstringCu rrent{get{returncurrent;}}objectIEnumerator.Current{ge t{returncurrent;}}publicvoidDispose(){}publicboolMov eNext(){switch(state){case0:current="hello";state=1;r eturntrue;case1:current="word";state=2;returntrue;def ault:break;}returnfalse;}publicvoidReset(){thrownewNo tImplementedException();}}}实现IEnumerablepublicclassMusiTi tles:IEnumerable{string[]names={"1","2","4","5"};p ublicIEnumeratorGetEnumerator(){for(inti=0;iames.Length;i++){yieldreturnnames[i];}}IEnumeratorIEnume rable.GetEnumerator(){returnGetEnumerator();}}元组数组合并了相同类型对象, 而元组合并了不同类型对象。Tuplet=Tuple.Create(1,2);Conso le.WriteLine(t.Item1.ToString(0+t.Item2.ToString()));结构比较IStruc turalComparable用于元组或数组的排序IStructuralEquatable两个元组或数组是否有相同的内容这两个 接口是显示实现的,所以在使用时需要把数组和元组转成这个接口。对于说明IStructuralEquqtable接口提示,使用实现IE quatable接口的类。IEquatable接口定义了一个强类型化的Equals()方法,比较FirstName和LastNam e属性的值;usingSystem;usingSystem.Collections.Generic;usingSystem. Linq;usingSystem.Text;namespace结构体比较{publicclassPersion:IE quatable{intid;stringfirstName;stringlastName;pu blicintId{get{returnid;}set{id=value;}}publicstr ingFirstName{get{returnfirstName;}set{firstName=value ;}}publicstringLastName{get{returnlastName;}set{las tName=value;}}publicboolEquals(Persionother){if(other ==null){base.Equals(other);}returnthis.id==other.Id&&th is.LastName==other.LastName&&this.FirstName==other.firstNam e;}publicoverridestringToString(){returnstring.Format("{0 },{1},{2}",Id,FirstName,LastName);}publicoverrideboolEqual s(objectobj){if(obj==null){returnbase.Equals(obj);}ret urnEquals(objasPersion);}publicoverrideintGetHashCode(){ returnId.GetHashCode();}}}varjanet=newPersion{FirstName ="Janet",LastName="Jackson"};Persion[]persions1={newPersi on{FirstName="Michael",LastName="Jackson"},janet};Pers ion[]persions2={newPersion{FirstName="Michael",LastName ="Jackson"},janet};Console.WriteLine(persions1==persions2) ;创建了两个Person数组,因为这一个人个变量persion1,persion2引用两不同的数组,Arrary没有重载==, 所以返回结果为False比较内容是否相等,可以用以下方法:if((persions1asIStructuralEquatabl e).Equals(persions2,EqualityComparer.Default)){Console .WriteLine("thesamecontent");}IStructuralEquatable.Equals方法 boolEquals(Objectother,IEqualityComparercomparer)通过EqualityC omparer类完成IEqualityComparer的一个默认实现。这个实现检查该类是否实现了IEquatable接口,并 调用IEquatable.Equals()方法。如果这个类没有实现IEquatable接口,就调用Ojbect的Equals()方 法。下面看看如何对组元执行相同的操作。vart1=Tuple.Create(1,"test"); vart2=Tuple.Create(1,"test");Console.WriteLine( t1.Equals(t2));Console.WriteLine((t1asIStructuralEquatable).Eq uals(t2,newTupleComparer()));publicclassTupleComparer:IEqual ityComparer{publicnewboolEquals(objectx,objecty){returnx.Equals(y);}publicintGetHashCode(objectobj){returnobj.GetHashCode();}}Console.WriteLine(t1.Equals(t2));Tuple类重写了object的Equals函数,这个方法获取一个EqualityComparer |
|