国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > .NET > 正文

通過(guò)C#實(shí)現(xiàn)集合類(lèi)縱覽.NET Collections及相關(guān)技術(shù)

2024-07-10 13:04:33
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

概述:在真正的對(duì)象化開(kāi)發(fā)項(xiàng)目中,我們通常會(huì)將常用的業(yè)務(wù)實(shí)體抽象為特定的類(lèi),如employee、customer、contact等,而多數(shù)的類(lèi)之間會(huì)存在著相應(yīng)的關(guān)聯(lián)或依存關(guān)系,如employee和customer通過(guò)contact而產(chǎn)生關(guān)聯(lián)、contact是依賴于employee和customer而存在的。在實(shí)際的對(duì)象應(yīng)用模塊中,可能會(huì)有這樣的需求:獲得一組客戶對(duì)象(即customers集合類(lèi)的實(shí)例,如customers),指向其中一個(gè)customer對(duì)象(如customers[i]),通過(guò)訪問(wèn)這個(gè)customer對(duì)象的屬性name(customers[i].name)和contacts(如customers[i].contacts)來(lái)查詢客戶的姓名和與該客戶的聯(lián)絡(luò)記錄,甚至遍歷contacts對(duì)象,查找該客戶的某次聯(lián)絡(luò)摘要(即customers.[i].contacts[x].summary)。為滿足以上集合類(lèi)的需求,對(duì)照.net framework 的平臺(tái)實(shí)現(xiàn),不難發(fā)現(xiàn).net在collections命名空間下提供了一系列實(shí)現(xiàn)集合功能的類(lèi),并且根據(jù)適用環(huán)境的不同為開(kāi)發(fā)者提供靈活多樣的選擇性:如通過(guò)索引訪問(wèn)使用廣泛的arraylist 和 stringcollection;通常在檢索后被釋放的先進(jìn)先出的queue和后進(jìn)先出stack;通過(guò)元素鍵對(duì)其元素進(jìn)行訪問(wèn)hashtable、sortedlist、listdictionary 和 stringdictionary;通過(guò)索引或通過(guò)元素鍵對(duì)其元素進(jìn)行訪問(wèn)的nameobjectcollectionbase 和 namevaluecollection;以及具有集合類(lèi)的特性而被實(shí)現(xiàn)在system.array下的array類(lèi)等。本文將通過(guò)實(shí)現(xiàn)具有代表性的 “集合類(lèi)”的兩種典型途徑,分析對(duì)比不同實(shí)現(xiàn)方式的差異性與適用環(huán)境,讓大家了解和掌握相關(guān)的一些技術(shù),希望為大家的學(xué)習(xí)和開(kāi)發(fā)工作起到拋磚引玉的作用(注:作者的調(diào)試運(yùn)行環(huán)境為.net framework sdk 1.1)。
1.采用從collectionbase抽象基類(lèi)繼承的方式實(shí)現(xiàn)customers集合類(lèi):
首先需要?jiǎng)?chuàng)建為集合提供元素的簡(jiǎn)單類(lèi)customer:

/// <summary>
/// 描述一個(gè)客戶基本信息的類(lèi)
/// </summary>
public class customer
{
/// <summary>
/// 客戶姓名
/// </summary>
public string name;

/// <summary>
/// 描述所有客戶聯(lián)絡(luò)信息的集合類(lèi)
/// </summary>
//public contacts contacts=new contacts();

/// <summary>
/// 不帶參數(shù)的customer類(lèi)構(gòu)造函數(shù)
/// </summary>
public customer()
{
system.console.writeline("initialize instance without parameter");
}

/// <summary>
/// 帶參數(shù)的customer類(lèi)構(gòu)造函數(shù)
/// </summary>
public customer(string name)
{
name=name;
system.console.writeline("initialize instance with parameter");
}
}

以上就是customer類(lèi)的簡(jiǎn)單框架,實(shí)用的customer類(lèi)可能擁有更多的字段、屬性、方法和事件等。值得注意的是在customer類(lèi)中還以公共字段形式實(shí)現(xiàn)了對(duì)contacts集合類(lèi)的內(nèi)聯(lián),最終可形成customer.contacts[i]的接口形式,但這并不是最理想的集合類(lèi)關(guān)聯(lián)方式,暫時(shí)將它注釋,稍后將詳加分析,這個(gè)類(lèi)的代碼重在說(shuō)明一個(gè)簡(jiǎn)單類(lèi)(相對(duì)于集合類(lèi)的概念范疇)的框架;另外,該類(lèi)還對(duì)類(lèi)構(gòu)造函數(shù)進(jìn)行了重載,為聲明該類(lèi)的實(shí)例時(shí)帶name參數(shù)或不帶參數(shù)提供選擇性。
接下來(lái)看我們的第一種集合類(lèi)實(shí)現(xiàn),基于從collectionbase類(lèi)派生而實(shí)現(xiàn)的customers類(lèi):
/// <summary>
/// customers 是customer的集合類(lèi)實(shí)現(xiàn),繼承自collectionbase
/// </summary>
public class customers: system.collections.collectionbase
{
public customers()
{

}
/// <summary>
/// 自己實(shí)現(xiàn)的add方法
/// </summary>
/// <param name="customer"></param>
public void add(customer customer)
{
list.add(customer);
}
/// <summary>
/// 自己實(shí)現(xiàn)的remove方法
/// </summary>
/// <param name="index"></param>
public void remove(int index)
{
if (index > count - 1 || index < 0)
{
system.console.writeline("index not valid!");
}
else
{
list.removeat(index);
}
}
}

以customers集合類(lèi)為例,結(jié)合集合輔助技術(shù),希望大家能了解掌握以下知識(shí):
從collectionbase繼承實(shí)現(xiàn)集合類(lèi)
customers類(lèi)采用從collectionbase繼承的方式,不再需要在類(lèi)內(nèi)聲明一個(gè)作為customer集合容器的list對(duì)象,因?yàn)閏ollectionbase類(lèi)已經(jīng)內(nèi)置了一個(gè)list對(duì)象,并已經(jīng)實(shí)現(xiàn)了count、clear、removeat等等ilist的重要接口(具體請(qǐng)參照msdn中的collectionbase 成員),只需要用戶顯示實(shí)現(xiàn)add、remove、indexof、insert等等接口,代碼中僅簡(jiǎn)單實(shí)現(xiàn)了add方法和remove方法的整參數(shù)版本作為示例。這種集合類(lèi)的實(shí)現(xiàn)具有簡(jiǎn)單高效的特點(diǎn),collectionbase已經(jīng)實(shí)現(xiàn)了較為完善的功能,實(shí)施者只要在其基礎(chǔ)上擴(kuò)展自己所需的功能即可。

索引器的簡(jiǎn)單實(shí)現(xiàn)
我們慣于操作數(shù)組的形式通常為array[i],集合類(lèi)可以看作是“對(duì)象的數(shù)組”,在c#中,幫助集合類(lèi)實(shí)現(xiàn)數(shù)組式索引功能的就是索引器:
public customer this[int index]
{
get
{
return (customer) list[index];
}
}
將以上代碼加入到customers類(lèi)后,就實(shí)現(xiàn)了以整形index為參數(shù),以list[index]強(qiáng)制類(lèi)型轉(zhuǎn)換后的customer類(lèi)型返回值的customers類(lèi)只讀索引器,使用者以customers[i].name的方式,就可以訪問(wèn)customers集合中第i個(gè)customer對(duì)象的姓名字段,是不是很神奇呢?文中的索引器代碼并未考慮下標(biāo)越界的問(wèn)題,越界的處理方式應(yīng)參照與之類(lèi)似的remove方法。作者在此只實(shí)現(xiàn)了索引器的get訪問(wèn),沒(méi)有實(shí)現(xiàn)set訪問(wèn)的原因?qū)⒃谙挛闹杏懻摗?br>
item的兩種實(shí)現(xiàn)方式
用過(guò)vb的朋友們一定都很熟悉customers.itme(i).name的形式,它實(shí)現(xiàn)了與索引器相同的作用,即通過(guò)一個(gè)索引值來(lái)訪問(wèn)集合體中的特定對(duì)象,但item在c#當(dāng)中應(yīng)該以怎樣的形式實(shí)現(xiàn)呢?首先想到的實(shí)現(xiàn)途徑應(yīng)該是屬性,但你很快就會(huì)發(fā)現(xiàn)c#的屬性是不支持參數(shù)的,所以無(wú)法把索引值作為參數(shù)傳入,折中的辦法就是以方法來(lái)實(shí)現(xiàn):
public customer item (int index)
{
return (customer) list[index];
}
這個(gè)item方法已經(jīng)可以工作了,但為什么說(shuō)是折中的辦法呢,因?yàn)閷?duì)item的訪問(wèn)將是采用customers.item(i).name的語(yǔ)法形式,與c#‘[]’作數(shù)組下標(biāo)的風(fēng)格不統(tǒng)一,顯的有些突兀,但如果希望在語(yǔ)法上做到統(tǒng)一,哪怕是性能受一些影響也無(wú)所謂的話有沒(méi)有解決之道呢?請(qǐng)看以下代碼:
public customers item
{
get
{
return this;
}
}
這是以屬性形式實(shí)現(xiàn)的item接口,但是由于c#的屬性不支持參數(shù),所以我們返回customers對(duì)象本身,也就是在調(diào)用customers對(duì)象item屬性時(shí)會(huì)引發(fā)對(duì)customers索引器的調(diào)用,性能有所下降,但是的確實(shí)現(xiàn)了customers.item[i].name的語(yǔ)法風(fēng)格統(tǒng)一。對(duì)比這兩種item的實(shí)現(xiàn),不難得出結(jié)論:以不帶參數(shù)的屬性形式實(shí)現(xiàn)的item依賴于類(lèi)的索引器,如果該類(lèi)沒(méi)有實(shí)現(xiàn)索引器,該屬性將無(wú)法使用;并且由于對(duì)item的訪問(wèn)重定向到索引器性能也會(huì)下降;唯一的理由是:統(tǒng)一的c#索引下標(biāo)訪問(wèn)風(fēng)格;采用方法實(shí)現(xiàn)的裨益正好與之相反,除了語(yǔ)法風(fēng)格較為別扭外,不存在依賴索引器、性能下降的問(wèn)題。魚(yú)與熊掌難以兼得,如何取舍應(yīng)依據(jù)開(kāi)發(fā)的實(shí)際需求決定。
中間語(yǔ)言的編譯缺省與attribute的應(yīng)用
如果你既實(shí)現(xiàn)了標(biāo)準(zhǔn)的索引器,又想提供名為“item”的接口,編譯時(shí)就會(huì)出現(xiàn)錯(cuò)誤“類(lèi)‘windowsapplication1.customers’已經(jīng)包含了“item”的定義”,但除了建立索引器外,你什么也沒(méi)有做,問(wèn)題到底出在哪里?我們不得不從.net中間語(yǔ)言il來(lái)尋找答案了,在.net命令行環(huán)境或visual studio .net 命令提示環(huán)境下,輸入ildasm,運(yùn)行.net framework msil 反匯編工具,通過(guò)主菜單中的‘打開(kāi)’加載只有索引器沒(méi)有item接口實(shí)現(xiàn)的可以編譯通過(guò)的.net pe執(zhí)行文件,通過(guò)直觀的樹(shù)狀結(jié)構(gòu)圖找到customers類(lèi),你將意外地發(fā)現(xiàn)c#的索引器被解釋成了一個(gè)名為item的屬性,以下是il反編譯后的被定義為item屬性的索引器代碼:
.property instance class windowsapplication1.customer
item(int32)
{
.get instance class windowsapplication1.customer windowsapplication1.customers::get_item(int32)
} // end of property customers::item
問(wèn)題總算水落石出,就是c#編譯器‘自作聰明’地把索引器解釋成了一個(gè)名為item的屬性,與我們期望實(shí)現(xiàn)的item接口正好重名,所以出現(xiàn)上述的編譯錯(cuò)誤也就在所難免。那么,我們有沒(méi)有方法告知編譯器,不要將索引器命名為缺省item呢?答案是肯定的。
解決方法就是在索引器實(shí)現(xiàn)之前聲明特性:
[system.runtime.compilerservices.indexername("item")]
定義這個(gè)indexername特性將告知csharp編譯器將索引器編譯成item而不是默認(rèn)的item ,修改之后的索引器il反匯編代碼為:
.property instance class windowsapplication1.customer
item(int32)
{
.get instance class windowsapplication1.customer windowsapplication1.customers::get_item(int32)
} // end of property customers::item
當(dāng)然你可以將索引器的生成屬性名定義成其它名稱而不僅限于item,只要不是il語(yǔ)言的保留關(guān)鍵字就可以。經(jīng)過(guò)了給索引器命名,你就可以自由地加入名為“item”的接口實(shí)現(xiàn)了。

以下為customer類(lèi)和customers類(lèi)的調(diào)試代碼,在作者的customers類(lèi)中,為說(shuō)明問(wèn)題,同時(shí)建立了以item為特性名的索引器、一個(gè)items方法和一個(gè)item屬性來(lái)實(shí)現(xiàn)對(duì)集合元素的三種不同訪問(wèn)方式,實(shí)際的項(xiàng)目開(kāi)發(fā)中,一個(gè)類(lèi)的索引功能不需要重復(fù)實(shí)現(xiàn)多次,可能只實(shí)現(xiàn)索引器或一個(gè)索引器加上一種形式的item就足夠了:
public class calltest
{
public static void main()
{
customers custs=new customers();
system.console.writeline(custs.count.tostring());//count屬性測(cè)試

customer acust=new customer();//將調(diào)用不帶參數(shù)的構(gòu)造函數(shù)
acust.name ="peter";
custs.add(acust);//add方法測(cè)試

system.console.writeline(custs.count.tostring());
system.console.writeline(custs.item[0].name);//調(diào)用item屬性得到
custs.items(0).name+="hu";//調(diào)用items方法得到
system.console.writeline(custs[0].name);//調(diào)用索引器得到

custs.add(new customer("linnet"));//將調(diào)用帶name參數(shù)的構(gòu)造函數(shù)
system.console.writeline(custs.count.tostring());
system.console.writeline(custs.items(1).name);//調(diào)用items方法得到
custs.item[1].name+="li";//調(diào)用items方法得到
system.console.writeline(custs[1].name);//調(diào)用索引器得到

custs.remove(0);//remove方法測(cè)試
system.console.writeline(custs.count.tostring());
system.console.writeline(custs[0].name);//remove有效性驗(yàn)證
custs[0].name="test passed" ;//調(diào)用索引器得到
system.console.writeline(custs.item[0].name);
custs.clear();
system.console.writeline(custs.count.tostring());//clear有效性驗(yàn)證

}
}
輸出結(jié)果為:
0
initialize instance without parameter
1
peter
peterhu
initialize instance with parameter
2
linnet
linnetli
1
linnetli
test passed
0

2.采用內(nèi)建arraylist對(duì)象的方式實(shí)現(xiàn)集合類(lèi):
或許有經(jīng)驗(yàn)的程序員們?cè)缫呀?jīng)想到,可以在一個(gè)類(lèi)中內(nèi)建一個(gè)數(shù)組對(duì)象,并在該類(lèi)中通過(guò)封裝對(duì)該對(duì)象的訪問(wèn),一樣能夠?qū)崿F(xiàn)集合類(lèi)。以下是采用這種思路的contact元素類(lèi)和contacts集合類(lèi)的實(shí)現(xiàn)框架:

public class contact
{
protected string summary;

/// <summary>
/// 客戶聯(lián)系說(shuō)明
/// </summary>
public string summary
{
get
{
system.console.writeline("getter access");
return summary;//do something, as get data from data source
}
set
{
system.console.writeline("setter access");
summary=value;// do something , as check validity or storage
}
}

public contact()
{

}
}

public class contacts
{
protected arraylist list;

public void add(contact contact)
{
list.add(contact);
}

public void remove(int index)
{
if (index > list.count - 1 || index < 0)
{
system.console.writeline("index not valid!");
}
else
{
list.removeat(index);
}
}

public int count
{
get
{
return list.count;
}
}

public contact this[int index]
{
get
{
system.console.writeline("indexer getter access");
return (contact) list[index];
}
set
{
list[index]=value;
system.console.writeline("indexer setter access ");
}

}

public contacts()
{
list=new arraylist();
}
}
通過(guò)這兩個(gè)類(lèi)的實(shí)現(xiàn),我們可以總結(jié)以下要點(diǎn):
采用arraylist的原因
在contacts實(shí)現(xiàn)內(nèi)置集合對(duì)象時(shí),使用了arraylist類(lèi),而沒(méi)有使用大家較為熟悉的array類(lèi),主要的原因有:在現(xiàn)有的.net v1.1環(huán)境中,array雖然已經(jīng)暴露了ilist.add、ilist.insert、ilist.remove、ilist.removeat等典型的集合類(lèi)接口,而實(shí)際上實(shí)現(xiàn)這些接口總是會(huì)引發(fā) notsupportedexception異常,microsoft是否在未來(lái)版本中實(shí)現(xiàn)不得而知,但目前版本的.net顯然還不支持動(dòng)態(tài)數(shù)組,在ms推薦的更改array大小的辦法是,將舊數(shù)組通過(guò)拷貝復(fù)制到期望尺寸的新數(shù)組后,刪除舊數(shù)組,這顯示是費(fèi)時(shí)費(fèi)力地在繞彎路,無(wú)法滿足集合類(lèi)隨時(shí)添加刪除元素的需求;arraylist已經(jīng)實(shí)現(xiàn)了add、clear、count、indexof、insert、remove、removeat等集合類(lèi)的關(guān)鍵接口,并且有支持只讀集合的能力,在上邊的contacts類(lèi)中,只通過(guò)極少的封裝代碼,就輕松地實(shí)現(xiàn)了集合類(lèi)。另一個(gè)問(wèn)題是我們?yōu)槭裁床徊捎门ccustomers類(lèi)似的從system.collections.arraylist繼承的方式實(shí)現(xiàn)集合類(lèi)呢?主要是由于將arraylist對(duì)象直接暴露于類(lèi)的使用者,將導(dǎo)致非法的賦值,如用戶調(diào)用arraylist.add方法,無(wú)論輸入的參數(shù)類(lèi)型是否為contact,方法都將被成功執(zhí)行,類(lèi)無(wú)法控制和檢查輸入對(duì)象的類(lèi)型與期望的一致,有悖該類(lèi)只接納contact類(lèi)型對(duì)象的初衷,也留下了極大的安全隱患;并且在contact對(duì)象獲取時(shí),如不經(jīng)過(guò)強(qiáng)制類(lèi)型轉(zhuǎn)換,contacts元素也無(wú)法直接以contact類(lèi)型形式來(lái)使用。
集合類(lèi)中的set
在集合類(lèi)的實(shí)現(xiàn)過(guò)程中,無(wú)論是使用索引器還是與索引器相同功能的“item”屬性,無(wú)可避免地會(huì)考慮是只實(shí)現(xiàn)getter形成只讀索引器,還是同時(shí)實(shí)現(xiàn)getter和setter形成完整的索引器訪問(wèn)。在上文的示例類(lèi)customers中就沒(méi)有實(shí)現(xiàn)索引器的setter,形成了只讀索引器,但在customer類(lèi)和customers類(lèi)的調(diào)試代碼,作者使用了容易令人迷惑的“custs[0].name="test passed"”的訪問(wèn)形式,事實(shí)上,以上這句并不會(huì)進(jìn)入到customers索引器的setter而是會(huì)先執(zhí)行customers索引器的getter得到一個(gè)customer對(duì)象,然后設(shè)置這個(gè)customer的name字段(如果name元素為屬性的話,將訪問(wèn)customer類(lèi)name屬性的setter)。那么在什么情況下索引器的setter才會(huì)被用到呢?其實(shí)只有需要在運(yùn)行時(shí)動(dòng)態(tài)地覆蓋整個(gè)元素類(lèi)時(shí),集合類(lèi)的setter才變得有意義,如“custs [i]=new customer ()”把一個(gè)全新的customer對(duì)象賦值給custs集合類(lèi)的已經(jīng)存在的一個(gè)元素,這樣的訪問(wèn)形式將導(dǎo)致customers的setter被訪問(wèn),即元素對(duì)象本身進(jìn)行了重新分配,而不僅僅是修改現(xiàn)有對(duì)象的一些屬性。也就是說(shuō),由于customers類(lèi)沒(méi)有實(shí)現(xiàn)索引器的setter 所以customers類(lèi)對(duì)外不提供“覆蓋”客戶集合中既有客戶的方法。與此形成鮮明對(duì)照的是contacts類(lèi)的索引器既提供對(duì)集合元素的getter,又提供對(duì)集合元素的setter,也就是說(shuō)contacts類(lèi)允許使用者動(dòng)態(tài)地更新contact元素。通過(guò)對(duì)contacts和contact兩個(gè)類(lèi)運(yùn)行以下測(cè)試可以很明確說(shuō)明這個(gè)問(wèn)題:
public class calltest
{
public static void main()
{
contacts cons=new contacts();
cons.add(new contact());
cons[0]=new contact();//trigger indexer setter
cons[0].summary="mail contact about ticket";
system.console.writeline(cons[0].summary);
}
}
理所當(dāng)然的輸出結(jié)果為:
indexer setter access
indexer getter access
setter access
indexer getter access
getter access
mail contact about ticket
明確認(rèn)識(shí)到了索引器setter的作用后,在類(lèi)的實(shí)現(xiàn)中就應(yīng)當(dāng)綜合實(shí)際業(yè)務(wù)特點(diǎn)、存取權(quán)限控制和安全性決定是否為索引器建立setter機(jī)制。
屬性-強(qiáng)大靈活的字段 合二為一的方法
在最初實(shí)現(xiàn)customer類(lèi)時(shí),我們使用了一個(gè)公共字段name,用作存取客戶的姓名信息,雖然可以正常的工作,但我們卻缺乏對(duì)name字段的控制能力,無(wú)論類(lèi)的使用者是否使用了合法有效的字段賦值,字段的值都將被修改;并且沒(méi)有很好的機(jī)制,在值改變時(shí)進(jìn)行實(shí)時(shí)的同步處理(如數(shù)據(jù)存儲(chǔ),通知相關(guān)元素等);另外,字段的初始化也只能放在類(lèi)的構(gòu)造函數(shù)中完成,即使在整個(gè)對(duì)象生命周期內(nèi)name字段都從未被訪問(wèn)過(guò)。對(duì)比我們?cè)赾ontact類(lèi)中實(shí)現(xiàn)的summary屬性,不難發(fā)現(xiàn),屬性所具有的優(yōu)點(diǎn):屬性可以在get時(shí)再進(jìn)行初始化,如果屬性涉及網(wǎng)絡(luò)、數(shù)據(jù)庫(kù)、內(nèi)存和線程等資源占用的方式,推遲初始化的時(shí)間,將起到一定的優(yōu)化作用;經(jīng)過(guò)屬性的封裝,真正的客戶聯(lián)系說(shuō)明summary被很好地保護(hù)了起來(lái),在set時(shí),可以經(jīng)過(guò)有效性驗(yàn)證再進(jìn)行賦值操作;并且在getter和setter前后,可以進(jìn)行數(shù)據(jù)存取等相關(guān)操作,這一點(diǎn)用字段是不可能實(shí)現(xiàn)的。所以我們可以得出結(jié)論,在字段不能滿足需求的環(huán)境中,屬性是更加強(qiáng)大靈活的替代方式。
另外,屬性整合了“get”和“set”兩個(gè)“方法”,而采用統(tǒng)一自然的接口名稱,較之java語(yǔ)言的object.getanything和object.setanything語(yǔ)法風(fēng)格更加親和(事實(shí)上,c#中的屬性只不過(guò)是對(duì)方法的再次包裝,具有g(shù)etter和setter的anything屬性在.net il中,依然會(huì)被分解成一個(gè)由anything屬性調(diào)用的get_anything和set_anything兩個(gè)方法)。
集合類(lèi)內(nèi)聯(lián)的方式
在文章最初的customer類(lèi)中使用了公共字段public contacts contacts=new contacts()實(shí)現(xiàn)了customer. contacts[]形式的集合類(lèi)內(nèi)聯(lián)接口,這是一種最為簡(jiǎn)單但缺乏安全性保護(hù)的集合類(lèi)集成方式,正如以上所述屬性的一些優(yōu)點(diǎn),采用屬性形式暴露一個(gè)公共的集合類(lèi)接口,在實(shí)際存取訪問(wèn)時(shí),再對(duì)受封狀保護(hù)的集合類(lèi)進(jìn)行操作才是更為妥當(dāng)完善的解決方案,如可以把customer類(lèi)內(nèi)聯(lián)的集合contacts的接口聲明改為:
protected contacts cons; //用于類(lèi)內(nèi)封裝的真正contacts對(duì)象
public contacts contacts//暴露在類(lèi)外部的contacts屬性
{
get
{
if (cons == null) cons=new contacts();
return cons;
}
set
{
cons=value;
}
}
最終,customers[i].contacts[x].summary的形式就被成功地實(shí)現(xiàn)了。
實(shí)例化的最佳時(shí)機(jī)
.net的類(lèi)型系統(tǒng)是完全對(duì)象化的,所有的類(lèi)型都是從system.object派生而來(lái),根據(jù)類(lèi)型的各自特點(diǎn),可以分為值類(lèi)型和引用類(lèi)型兩大陣營(yíng)。值類(lèi)型包括結(jié)構(gòu)(簡(jiǎn)單的數(shù)值型和布爾型也包括在內(nèi))和枚舉,引用類(lèi)型則包括了類(lèi)、數(shù)組、委托、接口、指針等,對(duì)象化的一個(gè)特點(diǎn)是直到對(duì)象實(shí)例化時(shí)才為對(duì)象分配系統(tǒng)資源,也就是說(shuō)靈活適時(shí)地實(shí)例化對(duì)象,對(duì)系統(tǒng)資源的優(yōu)化分配將產(chǎn)生積極意義。在一些文章中所建議的“l(fā)azy initialization”倡導(dǎo)在必要時(shí)才進(jìn)行對(duì)象的實(shí)例化,本著這樣的原則,從類(lèi)的外部來(lái)看,類(lèi)可以在即將被使用時(shí)再進(jìn)行初始化;在類(lèi)的內(nèi)部,如屬性之類(lèi)的元素,也可以不在構(gòu)造函數(shù)中初始化,而直到屬性的getter被真正訪問(wèn)時(shí)才進(jìn)行,如果屬性一直沒(méi)有被讀取過(guò),就不必要無(wú)意義地占用網(wǎng)絡(luò)、數(shù)據(jù)庫(kù)、內(nèi)存和線程等資源了。但是也并不是初始化越晚越好,因?yàn)槌跏蓟切枰獣r(shí)間的,在使用前才進(jìn)行初始化可能導(dǎo)致類(lèi)的響應(yīng)速度過(guò)慢,無(wú)法適應(yīng)使用者的實(shí)時(shí)需求。所以在資源占用和初始化耗時(shí)之間尋求一個(gè)平衡點(diǎn),才是實(shí)例化的最佳時(shí)機(jī)。

總結(jié)
本文圍繞實(shí)現(xiàn)集合類(lèi)的兩種途徑-從collectionbase繼承實(shí)現(xiàn)和內(nèi)建arraylist對(duì)象實(shí)現(xiàn),為大家展示了部分集合、索引器、屬性、特性的應(yīng)用以及.net環(huán)境中的類(lèi)構(gòu)造函數(shù)、對(duì)象優(yōu)化、類(lèi)關(guān)聯(lián)等其它相關(guān)知識(shí)。通過(guò)本文淺顯的示例和闡述,希望可以啟發(fā)讀者的靈感,推出更加精辟合理的基礎(chǔ)理論和應(yīng)用模型。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 富民县| 邮箱| 永宁县| 张家川| 浦北县| 茌平县| 加查县| 永胜县| 银川市| 保康县| 灵山县| 湘乡市| 桃江县| 华安县| 虞城县| 岳西县| 盘山县| 岳普湖县| 屯昌县| 开化县| 龙井市| 卓尼县| 金门县| 宣恩县| 弥勒县| 玛沁县| 青川县| 武山县| 四平市| 左权县| 桦川县| 县级市| 伊宁市| 固镇县| 云霄县| 赤峰市| 凯里市| 林甸县| 林口县| 醴陵市| 平安县|