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

首頁 > 開發 > 綜合 > 正文

包裝很好,里面是什么(轉自微軟)

2024-07-21 02:17:20
字體:
來源:轉載
供稿:網友
包裝很好,里面是什么?
作者:eric gunnerson
上個月,我們花了一些時間來學習如何找到與 c# 有關的東西。我收到一些詢問,問及有關 c# 或 .net 的 web 站點,所以我決定在專欄里增加一個 web 站點薈萃節目。寫信告訴我([email protected])您的站點,每個月我會隨機選擇五個站點,在專欄的最后列出它們的 url。
開場白結束,言歸正傳。

c# 中的類型


c# 和公共語言運行時 (clr) 中有兩種類型:引用類型(在 c# 中用類聲明)和值類型(在 c# 中用結構聲明)。引用和值類型在幾個重要方面有所不同。下表概括了這些區別:引用(類)值(結構)保留變量引用實際值活動值在堆中內聯(在堆棧中或與對象內聯)默認值null零= 表示復制引用復制值


值類型“感覺上”象一個數據。它包括預定義數值類型以及用戶定義的類型(如 complex 數字、pointrectangle)。如上文所述,值類型的變量是實際的值,所以在您使用變量時,通常處理的是實際的值。
int i = 123;int j = i;i = 55;

在第二次指定變量后,兩個獨立的變量包含相同的值。修改 i 的值不會改變 j 的值。
引用類型用于所有不能用作值類型的對象。引用類型的變量指向堆中對象的實例。這意味著在將一個變量指定給另一個變量時,只是指定了引用,而不是值。
employee e = new employee("fred");employee f = e;f.name = "barney";

在第二次指定變量后,e 和 f 指向同一對象。這意味著修改 f 的名稱也將改變 e 的名稱,因為它們引用同一實例。
這引發了一個相關話題。有些人可能一直奇怪,為什么 system.string 類中的函數不修改字符串,而總是返回字符串的新副本。這是因為字符串的類型為引用類型。如果對字符串調用 s.trim() 來修改內部字符串,您將遇到與 employee 相同的問題(這對字符串非常糟糕)。
修改類值的成員稱為“變更者”,而不具有任何變更者的類稱為不可變類。不可變類的存在可以使類的行為類似于值類,但不能寫入為值類。
如果您需要使用可變字符串類,請在 system.text 中試用 stringbuilder

轉向更簡單的模型


在語言中同時使用引用和值兩種類型是很重要的。值類型輕便高效,而引用類型適用于面向對象的開發。但是,現在我們有兩種類型,而我們需要的是更為簡單的模型,使用單一的、能夠囊括所有可能值的類型。
這樣一個通用基類能夠:
  • 調用任何值的虛函數。

  • 寫入能夠存儲任何值的集合類。

  • 替代 ole automation variant 類型。

為實現這一目的,公共語言運行時采用一種方法讓值類型在需要時轉化為引用類型,即通過稱為包裝的進程。被包裝的類型是通用基類,可以被各種類型的對象引用。

包裝和解除包裝


考慮下列代碼:
int value = 123;object o = value;   // 將 int 包裝到對象中int value2 = (int) o;   // 解除包裝到 value2

當賦值給 o 時,作為賦值的一部分,c# 編譯器將創建足夠容納堆中 int 的引用類型包裝,將值復制到該包裝,然后將包裝標記為實際類型(此處為 system.int32),以便運行時了解包裝的類型。
要從包裝中取值,必須使用強制類型裝換來指定包裝的類型(對象能夠保留任何類型)。在執行過程中,運行時將檢查對象變量引用的類型是否為強制類型轉換中指定的類型。如果類型正確,值將從包裝中復制回值類型變量。如果類型不正確,將導致異常。
請注意解除包裝過程中不會進行其他轉換;類型必須完全匹配。換句話說,如果我們編寫代碼:
long value2 = (long) o;   // 包裝的值是 int

其中 o 為已包裝的 int,則將導致異常。但是,我們可以這樣編寫:
long value2 = (long)(int) o;

則轉換將正常進行。
雖然這個示例演示了包裝和解除包裝,但可能會造成一些誤解。編寫代碼進行包裝的情況非常少見,一般是在將值類型的變量傳遞給類型對象參數時使用。
下面是一個小測驗。希望大家用心做。

測驗:您對包裝了解多少?


下面的代碼段給出了不同方案。請閱讀這些代碼,判斷哪一段代碼涉及包裝,而哪一段與包裝無關。有些方案(如 b)需要檢查多個位置。
// 方案 1int total = 35;datetime date = datetime.now;string s = string.format("your total was {0} on {1}", total, date);// 方案 bhashtable t = new hashtable();t.add(0, "zero");t.add(1, "one");// 方案 cdatetime d = datetime.now;string s = d.tostring();// 方案 ivint[] a = new int[2];a[0] = 33; // 方案 101arraylist a = new arraylist();a.add(33);// 方案 vimystruct s = new mystruct(15);iprocess ip = (iprocess) s;ip.process();

答案


請檢查答案并記錄分數。
方案 1

string.format() 將字符串作為第一個參數,對象作為第二個和第三個參數。intdatetime 都是值類型,所以它們都將被包裝以作為第二個和第三個參數。string.format() 使用這些參數,然后對每個參數調用 object.tostring() 將其轉換為字符串表示。如果您知道 int 將被包裝,得一分;如果知道 datetime 被包裝,得一分。
方案 b

hashtable.add() 有兩個參數,一個是關鍵字,另一個是值。它們都是類型對象。傳遞給關鍵字參數的值為整數,所以它必須被包裝,才能作為對象傳遞。傳遞給值參數的值為字符串(引用類型),所以字符串不需要包裝。每一點判斷正確各得一分。
方案 c

這段代碼很迷惑人。包裝的目的之一是實現對值類型參數的虛函數調用。tostring() 是對象的虛函數,所以,看起來在調用 tostring() 時,d 將被包裝。但是在轉換對象時沒有使用 d,所以不需要進行包裝。編譯器知道類型為 datetime 的變量只能為該類型(因為沒有導出的值類型,所以該變量不能為導出類型),所以它可以直接調用 datetime.tostring(),并設置“這個”引用,使其指向堆棧中的 d。如果回答正確,得一分。
方案 iv

clr 中的數組直接保存它們的值。例如,一個有五個元素的 int 數組有足夠的空間保存 5 個 int,而不是 5 個對象。如果認為此代碼與包裝無關,得一分。
方案 101

arraylist.add() 將對象作為參數,所以整數 33 將被包裝。如果回答正確,得一分。
方案 vi

接口為引用類型,所以在將值類型強制轉換到接口實現時,必須包裝值類型。如果了解這一點,得一分。

最后得分


將所有分數相加,并使用下表來檢查對包裝的了解程度:分數說明8對包裝很了解6-7了解,但有時明白,有時糊涂3-5尚可,請再接再厲1-2需要繼續學習0尚未入門

摘要


最后總結一下包裝。包裝使編寫和使用具有通用對象參數的函數變得簡單而直接。和許多美好的事情一樣,包裝也有不好的一面。下個月,我們將討論這些不好的方面是什么,如何減少負面影響,以及對 c# 的進一步說明(這會讓我們的 c# 生活更加美好)。

c# web 站點薈萃


下面的 web 站點是我通過電子郵件獲得的,不過我知道的僅此而已。如果那里的代碼無法編譯,計算機死機,或者遇到種種麻煩,請不要向我抱怨。
本月僅有兩項:
  • http://www.csharphelp.com
  • http://dotnetwire.com

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 东山县| 厦门市| 泾阳县| 甘肃省| 武川县| 虎林市| 菏泽市| 长治市| 汉阴县| 舞阳县| 洪洞县| 西青区| 浠水县| 横山县| 长春市| 深圳市| 班玛县| 南雄市| 潞西市| 长治县| 城固县| 肥东县| 濉溪县| 扬州市| 西乌珠穆沁旗| 苏州市| 左云县| 宜君县| 蒲江县| 蓝山县| 嘉定区| 库尔勒市| 怀仁县| 玛曲县| 四会市| 九龙城区| 石狮市| 咸宁市| 崇仁县| 洪雅县| 博客|