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

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

編輯:關於C語言

兩種轉換都失敗了。但是我告訴過你,強制轉化可以在用戶定義 的類型上完成。你應該想到強制轉化會成功。你是對的--(如果)它們跟像你想的 一樣是會成功的。但是轉換失敗了,因為你的編譯器為對象o產生的代碼是基於 編譯時類型。而對於運行時對象o,編譯器什麼也不知道,它們被視為 System.Obejct類型。編譯器認為,不存在System.Object類型到用戶類型MyType 的轉換。它檢測了System.Object和MyType的定義。缺少任意的用戶定義類型轉 換,編譯器(為我們)生成了用於檢測運行時對象o的代碼,並且檢測它是不是 MyType類型。因為對象o是SecondType類型,所以失敗了。編譯器並不去檢測實 際運行時對象o是否可以被轉換為MyType類型。

如果你使用下面的代碼段 ,你應該可以成功的完成從SecondType到MyType的轉換:

object o = Factory.GetObject( );
// Version three:
SecondType st = o as SecondType;
try {
 MyType t;
 t = ( MyType ) st;
 if ( t != null )
 {
  // work with T, it's a MyType.
 } else
 {
  // Report a null reference failure.
 }
} catch
{
 // report the failure.
}

你決不應該寫出如果糟糕的代碼,但它確實解決了一個很常 見的難題。盡管你決不應該這樣寫代碼,但你可以寫一個函數,用一個 System.Object參數來完成正確的轉換:

object o = Factory.GetObject( );
DOStuffWithObject( o );
private void DOStuffWithObject( object o2 )
{
 try {
  MyType t;
  t = ( MyType ) o2; // Fails. o is not MyType
  if ( t != null )
  {
   // work with T, it's a MyType.
  } else
  {
   // Report a null reference failure.
  }
 } catch
 {
  // report the conversion failure.
 }
}

記住,對一 個用戶定義類型的對象,轉換操作只是在編譯時,而不是在運行時。在運行時存 在介於o2和MyType之間的轉換並沒有關系,(因為)編譯器並不知道也不關心這些 。這樣的語句有不同的行為,這要取決於對st類型的申明:

t = ( MyType ) st;

(譯注:上面說的有些模糊。為什麼上面的代碼可能會有不 同的行為的呢?不同的什麼行為呢?主要就是:上面的這個轉化,是在編譯時還 是在運行時!如果st是用戶定義的類型,那麼上面的轉換是在編譯時。編譯器把 st當成為System.Object類型來編譯生成的IL代碼,因此在運行時是無法把一個 Object類型轉化為MyType類型的。解決辦法就是前面提到的方法,多加一條語句 ,先把Object類型轉換為SecondType,然後再強制轉化為MyType類型。但是如果 st是內置類型,那麼它的轉換是在運行時的,這樣的轉化或許會成功,看後面的 說明。因此,類似這樣的代碼:MyType m_mytype = (m_secondType as SecondType) as MyType;是不能通過編譯的,提示錯誤是無法在編譯時把 SecondType轉化為MyType,即使是重寫了轉換操作符。)

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