程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> Effective C#原則3:選擇is或者as操作符而不是做強制類型轉換(5)

Effective C#原則3:選擇is或者as操作符而不是做強制類型轉換(5)

編輯:關於C語言

foreach須要用強制轉換來同時支持對值類型和引用類型的轉換 。通過選擇強制轉化,foreach循環就可以采用一樣的行為,而不用管(循環)目 標對象是什麼類型。不管怎樣,因為foreach循環是用的強制轉換,因些它可能 會產生BadCastExceptions的異常。

因為IEnumberator.Current返回一個 System.Obejct對象,該對象沒有(重寫)轉換操作符,所以它們沒有一個滿足(我 們在上面做的)測試。

(譯注:這裡是說,如果你用一個集合存放了 SecondType,而你又想用MyType來對它進行foreach循環,那麼轉換是失敗的, 原因是在循環時,並不是用SecondType,而是用的System.Object,因此,在 foreach循環裡做的轉換與前面說的:MyType t = ( MyType ) o;是一樣的錯誤 ,這裡的o是SecondType,但是是以System.Object存在。)

正如你已經知 道的,一個存放了SecondType的集合是不能在前面的函數UseCollection中使用 循環的,這會是失敗的。用強制轉換的foreach循環不會在轉換時檢測循環集合 中的對象是否具有有效的運行時類型。它只檢測由IEnumerator.Current返回來 的System.Object是否可轉換為循環中使用的對象類型,這個例子中是MyType類 型。

最後,有些時候你想知道一個對象的精確類型,而不僅僅是滿足當 前可轉換的目標類型。as運算符在為任何一個從目標類型上派生的對象進行轉換 時返回true。GetType()方法取得一個對象的運行時對象,它提供了比is和as更 嚴格的(類型)測試。GetType()返回的類型可以與指定的類型進行比較(,從而知 道它是不是我們想要的類型)。

再次考慮這個函數:

public void UseCollection( IEnumerable theCollection )
{
 foreach ( MyType t in theCollection )
  t.DOStuff( );
}

如果你添加了一個派生自MyType的新類NewType,那麼 一個存放了NewType類型對象的集合可以很好的在UseCollection 函數中工作。

public class NewType : MyType
{
 // contents elided.
}

如果你想要寫一個函數,使它對所有MyType類型 的實例都能工作,上面的方法是非常不錯的。如果你只想寫一個函數,只對精確 的MyType對象有效,那你必須用精確的類型比較。這裡,你可以在foreach循環 的內部完成。大多數時候,認為運行時確定對象的精確類型是很重要的,是在為 對象做相等測試的時候。在大多數其它的比較中,由is和as提供的.isinst(譯注 :IL指令)比較,從語義上講已經是正確的了。

好的面向對象實踐告訴我 們,你應該避免類型轉換,但有些時候我沒別無選擇。當你無法避免轉換時,用 (C#)語言為我們提供的is和as運算符來清楚的表達你的意思吧。不同方法的強制 轉換有不同的規則。從語義上講,is和as在絕大多轉換上正確的,並當目標對象 是正確的類型時,它們總是成功的。應該選擇這些基本指令來轉換對象,至少它 們會如你所期望的那樣成功或者失敗;而不是選擇強制類型轉換,這轉換會產生 一些意想不到的副作用。

小結:翻譯的第三個原則。

今天下午在網上下載了電子版的書籍,因此 翻譯相對快一點點,至少不用自己輸入代碼了,那是很郁悶的事。繼續翻譯,爭 取在春節休假期間把所有的Items翻譯完。

我對書中所說的要注意的事項 基本上都自己測試一下,當然,如果是顯然正確的問題,就直接翻譯了,不做測 試。對於一些有疑點的地方,我盡可能的自己動手測試一下。繼續努力,相信後 面的翻譯會越來越快。

返回教程目錄

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved