C#入門學(xué)習(xí)之集合、比較和轉(zhuǎn)換_第1頁
C#入門學(xué)習(xí)之集合、比較和轉(zhuǎn)換_第2頁
C#入門學(xué)習(xí)之集合、比較和轉(zhuǎn)換_第3頁
C#入門學(xué)習(xí)之集合、比較和轉(zhuǎn)換_第4頁
C#入門學(xué)習(xí)之集合、比較和轉(zhuǎn)換_第5頁
已閱讀5頁,還剩16頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第C#入門學(xué)習(xí)之集合、比較和轉(zhuǎn)換目錄一、集合1、使用集合2、自定義集合3、索引符4、關(guān)鍵字值集合和IDictionary5、迭代器6、迭代器和集合7、深度復(fù)制二、比較1、類型比較封箱和拆箱is運(yùn)算符2、值比較運(yùn)算符重載IComparable和IComparer接口三、轉(zhuǎn)換1、重載轉(zhuǎn)換運(yùn)算符2、as運(yùn)算符

一、集合

C#中的數(shù)組是作為System.Array類的實(shí)例來執(zhí)行的,它們是集合類中的一種。

集合類一般用于處理對(duì)象列表,其功能是通過執(zhí)行System.Collection中的接口實(shí)現(xiàn)的。

集合的功能可以通過接口來實(shí)現(xiàn),該接口可以使用基本基本集合類,也可以創(chuàng)建自定義的集合類。

System.Collections命名空間有很多接口提供了基本的集合功能:

IEnumerable:公開枚舉數(shù),該枚舉數(shù)支持在非泛型集合上進(jìn)行簡(jiǎn)單迭代ICollection:定義所有非泛型集合的大小、枚舉數(shù)和同步方法IList:表示可按照索引單獨(dú)訪問的對(duì)象的非泛型集合IDictionary:表示鍵/值對(duì)的非通用集合

System.Array類繼承了IList,ICollection和IEnumerable。但不支持IList的一些高級(jí)功能,而且是一個(gè)大小固定的項(xiàng)目列表。

1、使用集合

Systems.Collections中的一個(gè)類System.Collections.ArrayList,也執(zhí)行IList,ICollection和IEnumerable接口,但與數(shù)組不同,它是大小可變的

使用System.Array類的集合(數(shù)組),必須用固定的大小來初始化數(shù)組

例如:

Animal[]animalArray=newAnimal[2];

使用System.ArrayList類的集合,不需要初始化其大小

例如:

ArrayListanimalArrayList=newArrayList();

這個(gè)類還有兩個(gè)構(gòu)造函數(shù):

1把現(xiàn)有集合作為參數(shù)復(fù)制到新實(shí)例中

2用一個(gè)int參數(shù)設(shè)置集合的容量,不過實(shí)際內(nèi)容超過容量時(shí)會(huì)自動(dòng)增加

初始化數(shù)組,需要給這個(gè)項(xiàng)目賦予初始化了的對(duì)象

例如:

CowmyCow1=newCow("Deirdre");

animalArray[0]=myCow1;

animalArray[1]=newChicken("Ken");

可以用這兩種方式初始化數(shù)組

對(duì)于ArrayList集合,需要用Add()方法添加新項(xiàng)目

例如:

CowmyCow2=newCow("Hayley");

animalArrayList.Add(myCow2);

animalArrayList.Add(newChicken("Roy"));

在添加萬項(xiàng)目之后,就可以用與數(shù)組相同的語法重寫他們

例如:

animalArrayList[1]=newChicken("Roy2")

Array數(shù)組和ArrayList集合都支持foreach結(jié)構(gòu)來迭代

例如:

foreach(AnimalmyAnimalinanimalArray)

foreach(AnimalmyAnimalinanimalArrayList)

}

Array數(shù)組使用Length屬性獲取項(xiàng)目的個(gè)數(shù)

例如:

intanimalCount=animalArray.Length;

ArrayList集合使用Count屬性獲取項(xiàng)目的個(gè)數(shù)

intanimalCount2=animalArrayList.Count;

Array數(shù)組是強(qiáng)類型化的,可以直接使用數(shù)組的類型來存儲(chǔ)項(xiàng)目

即可以直接訪問項(xiàng)目的屬性和方法

例如:

對(duì)于類型是Animal的數(shù)組,F(xiàn)eed()是類Animal的方法

animalArray[0].Feed();

但對(duì)于類Animal派生類的方法,就不能直接調(diào)用,需要強(qiáng)制轉(zhuǎn)換

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

ArrayList集合是System.Object對(duì)象的集合,通過多態(tài)性賦給Animal對(duì)象

必須進(jìn)行數(shù)據(jù)類型轉(zhuǎn)換

例如:

((Animal)animalArrayList[0]).Feed();

((Chicken)animalArrayList[1]).LayEgg();

使用Remove()和RemoveAt()方法刪除項(xiàng)目

Remove從ArrayList中移除特定對(duì)象的第一個(gè)匹配項(xiàng)(參數(shù)為特定對(duì)象)

RemoveAt移除ArrayList的指定索引處的元素(參數(shù)為索引值)

刪除項(xiàng)目后,會(huì)使其他項(xiàng)目在數(shù)組中移動(dòng)一個(gè)位置

使用AddRange()和InsertRange()方法可以一次添加多個(gè)項(xiàng)目

AddRange將ICollection的元素添加到ArrayList的末尾

InsertRange將集合中的某個(gè)元素插入ArrayList的指定索引處。

例如:

animalArrayList.AddRange(animalArray);

使用IndexOf()方法獲取指定項(xiàng)目的索引值

IndexOf返回ArrayList或它的一部分中某個(gè)值的第一個(gè)匹配項(xiàng)的從零開始的索引。

可以通過索引值直接訪問選項(xiàng)

例如:

intiIndex=animalArrayList.IndexOf(myCow1);

((Animal)animalArrayList[iIndex]).Feed();

2、自定義集合

可以從一個(gè)類派生自定義的集合

推薦使用System.Collections.CollectionBase類。CollectionBase類有接口IEnumerable,ICollection,和IList

List屬性可以通過Ilist接口訪問項(xiàng)目,InnerList屬性用于存儲(chǔ)項(xiàng)目的ArrayList對(duì)象

例如:

publicclassAnimals:CollectionBase

publicvoidAdd(AnimalnewAnimal)

List.Add(newAnimal);

publicvoidRemove(AnimaloldAnimal)

List.Remove(oldAnimal);

publicAnimals()

}

這個(gè)類用于生成Animal類型的集合,可以用foreach訪問其成員:

AnimalsanimalCollection=newAnimals();

animalCollection.Add(newCow("Sarah"));

foreach(AnimalmyAnimalinanimalCollection)

}

如果要以索引的方式訪問項(xiàng)目,就需要使用索引符

3、索引符

索引符是一種特殊類型的屬性,可以把它添加到類中,提供類似數(shù)組的訪問。

最常見的一個(gè)用法是對(duì)項(xiàng)目執(zhí)行一個(gè)數(shù)字索引

例如:

在Animals集合中添加一個(gè)索引符

publicclassAnimals:CollectionBase

publicAnimalthis[intanimalIndex]

return(Animal)List[animalIndex];

List[animalIndex]=value;

}

this關(guān)鍵字與方括號(hào)一起,方括號(hào)中是索引參數(shù)

對(duì)List使用一個(gè)索引符,而且顯示聲明了類型,因?yàn)镮List接口返回的是System.Object對(duì)象

現(xiàn)在可以用索引的方式訪問項(xiàng)目:

animalCollection[0].Feed();

4、關(guān)鍵字值集合和IDictionary

集合還可以執(zhí)行類似的IDictionary接口,通過關(guān)鍵字值進(jìn)行索引

使用基類DictionaryBase,它也執(zhí)行IEnumerable和ICollection接口,提供了對(duì)任何集合都相同的集合處理功能

例如:

publicclassAnimals:DictionaryBase

publicvoidAdd(stringnewID,AnimalnewAnimal)

Dictionary.Add(newID,newAnimal);

publicvoidRemove(stringanimalID)

Dictionary.Remove(animalID);

publicAnimals()

publicAnimalthis[stringanimalID]

return(Animal)Dictionary[animalID];

Dictionary[animalID]=value;

}

這樣添加了Add()方法,Remove()方法和一個(gè)通過關(guān)鍵字訪問項(xiàng)目的方法

其中Dictionary是包含在DictionaryBase實(shí)例中的元素的列表

DictionaryBase集合和CollectionBase集合在foreach的工作方式不同,

DictionaryBase提供的是DictionaryEntry結(jié)構(gòu),需要通過Value成員獲取對(duì)象本身

例如:

CollectionBase集合:

foreach(AnimalmyAnimalinanimalCollection)

myAnimal.Feed();

}

DictionaryBase集合:

foreach(DictionaryEntrymyEntryinanimalCollection)

((Animal)myEntry.Value).Feed();

}

5、迭代器

通過IEnumerable接口,可以使用foreach循環(huán)獲取對(duì)象

foreach循環(huán),迭代collectionObject的過程:

1調(diào)用Collection的GetEnumerator()方法返回一個(gè)IEnumerator引用

該方法也可以通過IEnumerable接口的實(shí)現(xiàn)代碼獲得

2調(diào)用IEnumerator接口的MoveNext()方法,將枚舉數(shù)推進(jìn)到集合的下一個(gè)元素

3如果MoveNext()方法返回true,使用IEnumerator接口的Current屬性獲取對(duì)象的引用,用于foreach循環(huán)

4重復(fù)前兩個(gè)步驟,直至MoveNext()返回false時(shí),循環(huán)停止

迭代器是一個(gè)按順序提供要在foreach循環(huán)中使用的所有值的代碼塊

一般這個(gè)代碼塊是一個(gè)方法,也可以使用屬性訪問器和其他代碼塊作為迭代器

代碼塊的返回值可能是IEnumerable或IEnumerator接口類型:

1如果要迭代一個(gè)類,可使用方法IEnumerator(),其返回類型是IEnumerator

2如果要迭代一個(gè)類成員,則使用IEnumerable

在迭代器塊中,使用yield關(guān)鍵字選擇要在foreach循環(huán)中使用的值

語法:

yieldreturnvalue;

例如:

publicstaticIEnumerableSimpleList()

yieldreturn"string1";

yieldreturn"string2";

yieldreturn"string3";

publicstaticvoidMain(string[]args)

foreach(stringiteminSimpleList())

Console.WriteLine(item);

Console.ReadKey();

}

這里SimpleList就是迭代器塊,是一個(gè)方法,使用IEnumerable返回類型

可以從yield語句中返回任意類型

可以中斷信息返回foreach循環(huán)過程

語法:yieldbreak;

6、迭代器和集合

迭代器可以用于迭代儲(chǔ)存在目錄類型的集合中的對(duì)象

例如:

publicnewIEnumeratorGetEnumerator()

foreach(objectanimalinDictionary.Values)

yieldreturn(Animal)animal;

}

迭代集合中的對(duì)象:

foreach(AnimalmyAnimalinanimalCollection)

}

7、深度復(fù)制

使用System.Object.MemberwiseClone()方法可以進(jìn)行陰影復(fù)制

對(duì)于值類型成員,沒什么問題

但對(duì)于引用類型成員,新對(duì)象和源對(duì)象的成員將指向同一個(gè)引用對(duì)象

例如:

publicclassContent

publicintVal;

publicclassCloner

publicContentMyContent=newContent();

publicCloner(intnewVal)

MyContent.Val=newVal;

publicobjectGetCopy()

returnMemberwiseClone();

}

執(zhí)行:

ClonermySource=newCloner(5);

ClonermyTarget=(Cloner)mySource.GetCopy();

intiVal1=myTarget.MyContent.Val;

mySource.MyContent.Val=2;

intiVal2=myTarget.MyContent.Val;

結(jié)果:

iVal1是5,iVal2是2

但有時(shí)候需要的是分別引用各自的對(duì)象,使用深度復(fù)制就可以解決

標(biāo)準(zhǔn)方式是添加一個(gè)ICloneable接口,該接口有一個(gè)Clone()方法

該方法不帶參數(shù),返回一個(gè)對(duì)象類型

例如:

publicclassContent

publicintVal;

publicclassCloner:ICloneable

publicContentMyContent=newContent();

publicintiVal=0;

publicCloner(intnewVal)

MyContent.Val=newVal;

publicobjectClone()

ClonerclonedCloner=newCloner(MyContent.Val);

clonedCloner.iVal=iVal;

returnclonedCloner;

}

通過Cloner對(duì)象的Val字段創(chuàng)建一個(gè)相同的Cloner對(duì)象

如果有值成員需要復(fù)制,那必須給新對(duì)象添加上這個(gè)成員

這樣就能復(fù)制一個(gè)與源對(duì)象相同而互相獨(dú)立的新對(duì)象

用GetCopy換成Clone,執(zhí)行相同的程序,結(jié)果:

iVal1是5,iVal2是5

二、比較

1、類型比較

比較對(duì)象時(shí),需要先知道對(duì)象的類型,可以使用GetType()方法

配合typeof()運(yùn)算符一起使用,就可以確定對(duì)象的類型

if(myObj.GetType()==typeof(MyComplexClass))

//myObjisaninstanceoftheclassMyComplexClass.

}

封箱和拆箱

處理值類型時(shí)后臺(tái)的操作:

封箱(boxing)是把值類型轉(zhuǎn)換為System.Object類型或由值類型實(shí)現(xiàn)的接口類型

拆箱(unboxing)是相反的過程

例如:

結(jié)構(gòu)類型:

structMyStruct

publicintVal;

}

把類型結(jié)構(gòu)放在object類型變量中封箱:

MyStructvalType1=newMyStruct();

valType1.Val=5;

objectrefType=valType1;

這里創(chuàng)建了一個(gè)MyStruct類型的valType1,給成員賦值后封箱到對(duì)象refType中

這種方式的封裝,將包含值類型的一個(gè)副本的引用,而不是源值的引用

驗(yàn)證:

valType1.Val=6;

MyStructvalType2=(MyStruct)refType;

結(jié)果valType2.Val是5而不是6

如果對(duì)個(gè)引用類型進(jìn)行封裝,將包含源值的引用

例如:

classMyStruct

publicintVal;

}

執(zhí)行相同的操作,得到valType2.Val的值是6

可以把值類型封箱到一個(gè)接口類型中:

interfaceIMyInterface

structMyStruct:IMyInterface

publicintVal;

}

把結(jié)構(gòu)封箱到IMyInterface類型中:

MyStructvalType1=newMyStruct();

IMyInterfacerefType=valType1;

拆箱:

MyStructValType2=(MyStruct)refType;

封箱是在沒有用戶干涉的情況下進(jìn)行的

拆箱一個(gè)值需要進(jìn)行顯式轉(zhuǎn)換(封箱是隱式的轉(zhuǎn)換)

訪問值類型的內(nèi)容前,必須進(jìn)行拆箱

is運(yùn)算符

is運(yùn)算符可以檢查對(duì)象是否是給定的類型,或者是否可以轉(zhuǎn)換為給定的類型

語法:

is

1如果是一個(gè)類類型,也是該類型,或繼承了該類型,或封箱到該類型中,則返回true

2如果是一個(gè)接口類型,也是該類型,或是實(shí)現(xiàn)該接口的類型,則返回true

3如果是一個(gè)值類型,也是該類型,或封箱到該類型中,則返回true

2、值比較

運(yùn)算符重載

要重載運(yùn)算符,可給類添加運(yùn)算符類型成員(必須是static)

例如:

重載+運(yùn)算符:

publicclassAddClass1

publicintval;

publicstaticAddClass3operator+(AddClass1op1,AddClass2op2)

AddClass3returnVal=newAddClass3();

returnVal.val=op1.val+op2.val;

returnreturnVal;

publicclassAddClass2

publicintval;

publicclassAddClass3

publicintval;

}

運(yùn)算符重載與標(biāo)準(zhǔn)靜態(tài)方法聲明類似,但它使用關(guān)鍵字operator和運(yùn)算符本身

使用:

AddClass1op1=newAddClass1();

op1.val=5;

AddClass2op2=newAddClass2();

op2.val=4;

AddClass3op3=op1+op2;

結(jié)果op3.val的值是9

注意:如果混合了類型,操作數(shù)數(shù)序必須與運(yùn)算符重載參數(shù)順序相同

可以重載的運(yùn)算符:

一元運(yùn)算符:+,-,!,~,++,--,true,false

二元運(yùn)算符:+,-,*,/,%,,|,^,,

比較運(yùn)算符:==,!=,,,=,=

注意:

如果重載true或false運(yùn)算符,可以在布爾表達(dá)式中使用類,例如if(op1){}

運(yùn)算符如和必須成對(duì)重載,但可以使用其他運(yùn)算符來減少代碼

例如:

classAddclass1

publicintval;

publicstaticbooloperator=(Addclass1op1,Addclass2op2)

returnop1.val=op2.val;

publicstaticbooloperator(Addclass1op1,Addclass2op2)

return!(op1=op2);

publicstaticbooloperator=(Addclass1op1,Addclass2op2)

returnop1.val=op2.val;

publicstaticbooloperator(Addclass1op1,Addclass2op2)

return!(op1=op2);

}

同時(shí)適用于==和!=,常常需要重寫Object.Equals()和Object.GetHashCode()

classAddclass1

publicintval;

publicstaticbooloperator==(Addclass1op1,Addclass1op2)

return(op1.val==op2.val);

publicstaticbooloperator!=(Addclass1op1,Addclass1op2)

return!(op1==op2);

publicoverrideboolEquals(objectobj)

returnval==((Addclass1)obj).val;

publicoverrideintGetHashCode()

returnval;

}

IComparable和IComparer接口

IComparable和IComparer接口是比較對(duì)象的標(biāo)準(zhǔn)方式

區(qū)別:

IComparable在要比較的對(duì)象的類中實(shí)現(xiàn),可以比較該對(duì)象和另一個(gè)對(duì)象

IComparer在一個(gè)單獨(dú)的類中實(shí)現(xiàn),可以比較任意兩個(gè)對(duì)象

.NetFramework在類Comparer上提供了IComparer接口的默認(rèn)實(shí)現(xiàn)方式,類Comparer位于System.Collections命名空間中,可以對(duì)簡(jiǎn)單類型以及支持IComparable接口的任意類型進(jìn)行特定文化的比較

publicclassSamplesComparer

publicstaticvoidMain()

Stringstr1="llegar";

Stringstr2="lugar";

Console.WriteLine("Comparing\"{0}\"and\"{1}\"",str1,str2);

//UsestheDefaultInvariantComparer.

Console.WriteLine("InvariantComparer:{0}",Comparer.DefaultInvariant.Compare(str1,str2));

//UsestheComparerbasedontheculture"es-ES"(Spanish-Spain,internationalsort).

ComparermyCompIntl=newComparer(newCultureInfo("es-ES",false));

Console.WriteLine("InternationalSort:{0}",myCompIntl.Compare(str1,str2))

}

一般使用IComparable給出類的默認(rèn)比較代碼,使用其他類給出非默認(rèn)的比較代碼

IComparable提供一個(gè)CompareTo()方法比較兩個(gè)對(duì)象,并返回一個(gè)int值

例如:

classPerson:IComparable

publicstringName;

publicintAge;

publicPerson(stringname,intage)

Name=name;

Age=age;

publicintCompareTo(objectobj)

if(objisPerson)

PersonotherPerson=objasPerson;

returnthis.Age-otherPerson.Age;

else

thrownewArgumentException("ObjecttocomparetoisnotaPersonobject.");

}

主程序代碼

classProgram

staticvoidMain(string[]args)

Personperson1=newPerson("Jim",30);

Personperson2=newPerson("Bob",25);

if(person1.CompareTo(person2)==0)

Console.WriteLine("Sameage");

elseif(person1.CompareTo(person2)0)

Console.WriteLine("person1isOlder");

else

Console.WriteLine("person1isYounger");

}

IComparer提供一個(gè)Compare()方法,接受兩個(gè)對(duì)象返回一個(gè)整型結(jié)果

例如:

publicclassPersonComparer:IComparer

publicstaticIComparerDefault=newPersonComparer();

publicintCompare(objectx,objecty)

if(xisPersonyisPerson)

returnComparer.Default.Compare(((Person)x).Age,((Person)y).Age);

else

thrownewArgumentException(

"OneorbothobjectstocomparearenotPersonobjects.");

}

主程序:

classProgram

staticvoidMain(string[]args)

Personperson1=newPerson("Jim",30);

Personperson2=newPerson("Bob",25);

if(PersonComparer.Default.Compare(person1,person2)==0)

Console.WriteLine("Samea

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論