<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
      Fork me on GitHub

      C#中 As 和強制轉換的總結

      1.1.1 摘要

      C#是一門強類型語言,一般情況下,我們最好避免將一個類型強制轉換為其他類型,但有些時候難免要進行類型轉換。

      先想想究竟哪些操作可以進行類型轉換(先不考慮.NET提供的Parse),一般我們都有以下選擇:

      • 使用as操作符轉換,
      • 使用傳統C風格的強制轉型
      • 使用is來做一個轉換測試,然后再使用as操作符或者強制轉

       

      1.1.2 正文

      正確的選擇應該是盡可能地使用as操作符,因為它比強制轉型要安全,而且在運行時層面也有比較好的效率(注意的是as和is操作符都不執行任何用戶自定義的轉換,只有當運行時類型與目標轉換類型匹配時,它們才會轉換成功)。

      現在我們通過一個簡單的例子說明as和強制轉換之間的區別,首先我們定義一間獲取不同類型對象的工廠,然后我們把未知類型轉換為自定義類型。

       

      object o = Factory.GetObject();
      MyType t
      = o as MyType;
      if (t == null)
      {
      //轉換成功
      }
      else
      {
      //轉換失敗
      }


      object o = Factory.GetObject();
      try
      {
      MyType t
      = (MyType) o;
      if (t != null)
      {
      ////轉換成功
      }
      else
      {
      ////轉換失敗
      }

      }
      catch
      {
      ////異常處理
      }

       

      通過上述代碼我們發現as類型轉換失敗時值為null不拋出異常,但強制轉換如果轉換失敗會拋出異常所以我們要添加異常處理。

      現在我們對as和強制轉換有了初步的了解,假設現在我們定義了一個抽象類Foo,然后Foo1繼承于它,并且再定義一個基類Logger,在Foo1中定義與Logger類型隱式轉換具體如下:

      Foo1 myFoo; //// Inherits abstract class.
      Logger myFoo; //// base class.

      public class Foo1 : Foo
      {
      private Logger _value;

      /// <summary>
      /// 隱式自定義類型轉換。
      /// </summary>
      /// <param name="foo1"></param>
      /// <returns></returns>
      public static implicit operator Logger(Foo1 foo1)
      {
      return foo1._value;
      }
      }

      現在我們猜猜看以下的類型轉換是否成功(提示:從編譯和運行時類型轉換角度考慮)。

      object myFoo = container.Resolve<Foo>(); //獲取未Foo1類型

      try
      {
      Logger myFoo1
      = (Logger)myFoo;
      if (myFoo1 != null)
      {
      Console.WriteLine(
      "Covert successful.");
      }
      }
      catch
      {
      Console.WriteLine(
      "Covert failed.");
      }

      相信聰明的大家已經想出答案了,激動人心的時刻到了現在讓我們公布答案:轉換失敗拋出異常。

      圖1轉換失敗結果

       

      首先我們要從編譯和運行時角度來分析,在編譯時myFoo的類型為System.Object,這時編譯器會檢測是否存在自定義由Object到Logger的類型轉換。如果沒有找到合適轉換,編譯器將生成代碼檢測myFoo的運行時類型和Logger比較,由于myFoo的運行時類型為Foo1,而且我們自定義了由Foo1到Logger的類型轉換,估計這樣可以轉換成功了吧!然而恰恰沒有轉換成功,這究竟是什么原因呢?讓我們了解一下編譯器對于隱式類型轉換的原理吧。

      圖2編譯和運行時自定義類型轉換

       

      通過上圖我們發現用戶自定義的轉換操作符只作用于對象的編譯時類型,而非運行時類型上,OK現在讓修改一下代碼讓我們編譯器認識自定義類型中。

      using (IUnityContainer container = new UnityContainer())
      {
      UnityConfigurationSection section
      = (UnityConfigurationSection)
      ConfigurationManager.GetSection("unity"); //獲取container名稱為CfgClass下的配置
      section.Containers["CfgClass"].Configure(container);
      object tempFoo = container.Resolve<Foo>(); //獲取未Foo1類型
      Foo1 myFoo = tempFoo as Foo1; //使用as先把object轉型為Foo1
      try
      {
      Logger myFoo1
      = (Logger)myFoo;
      if (myFoo1 != null)
      {
      Console.WriteLine(
      "Covert successful.");
      }
      }
      catch
      {
      Console.WriteLine(
      "Covert failed.");
      }

      Console.ReadKey();
      }

      圖3轉換成功結果

       

      現在類型可以轉換成功,這是因為編譯器使用了我們自定義的隱式轉換,由于myFoo這次的編譯類型為Foo1,編譯器首先查找是否存在Foo1和Logger自定義轉換類型,由于我們定義了一種由Foo1到Logger的隱式類型轉換所以轉換成功。

      通過上述我們發現了as給我們帶來的好處,但是有一點我們要注意的是as只能用于引用類型不能用于值類型。那我就有個問題了在進行類型轉換之前如果我們并不知道要轉換的是值類型還是引用類型,那該怎么辦呢?現在是is登場的時候了。

      bject tempFoo = container.Resolve<Foo>(); //獲取未Foo1類型
      int myInt = tempFoo as int; //compile error

      as不能用于值類型,這是因為值類型不能為null(注意:C#2.0中,微軟提供了Nullable類型,允許用它定義包含null值,即空值的數據類型)像這種情況我們應該使用強制類型轉換。

          object tempFoo = container.Resolve<Foo>(); //獲取未Foo1類型
      try
      {
      int myInt = (int)tempFoo; //轉換成功
            if (myFoo1 != null)
      {
      Console.WriteLine(
      "Covert successful.");
      }
      }
      catch
      {
      Console.WriteLine(
      "Covert failed.");
      }

      大家可以發現和我們之前使用的強制轉換類似,而且還有處理異常,現在修改一下我們代碼讓它更加簡潔實現如下:

      object tempFoo = container.Resolve<Foo>(); //獲取未Foo1類型
      int i = 0; //值類型轉換
      if (tempFoo is int)
      {
      i
      = (int) tempFoo;
      }


      object tempFoo = container.Resolve<Foo>(); //獲取未Foo1類型
      Logger myFoo1 = null; //引用類型轉換
      if (tempFoo is Logger)
      {
      myFoo1
      = tempFoo as Logger;
      }

      1.1.3 總結

      as和強制轉換之間最大的區別就在于如何處理用戶自定義的轉換。操作符 as和 is 都只檢查被轉換對象的運行時類型,并不執行其他的操作。如果被轉換對象的運行時類型既不是所轉換的目標類型,也不是其派生類型,那么轉型將告失敗。但是強制轉型則會使用轉換操作符來執行轉型操作,這包括任何內建的數值轉換(如:long轉int)。

      一般情況我們應該先考慮使用as進行類型轉換,然后再考慮使用is,最后才考慮使用強制轉換。

       

      as

      強制轉換

      轉換失敗是否拋出異常

      No

      Yes

      支持值類型和引用類型轉換

      只支持引用類型

      Yes

      posted @ 2011-05-13 21:05  JK_Rush  閱讀(45594)  評論(13)    收藏  舉報
      主站蜘蛛池模板: 中文人妻无码一区二区三区在线 | 色天天天综合网色天天| 色欲aⅴ亚洲情无码av蜜桃| 国产漂亮白嫩美女在线观看| 不卡视频在线一区二区三区| 九九综合va免费看| 一道本AV免费不卡播放| 国产一区二区三区不卡自拍| 视频一区二区不中文字幕| 成人拍拍拍无遮挡免费视频| 人妻蜜臀久久av不卡| 九九热免费在线视频观看 | 国产叼嘿视频一区二区三区| 亚洲人成网网址在线看| 日韩一区二区三区理伦片| 中文字幕av国产精品| 女厕偷窥一区二区三区| 亚洲区激情区无码区日韩区 | 色窝窝免费一区二区三区| 香港日本三级亚洲三级| 成人午夜无人区一区二区| 国产一区二区三区禁18| 亚洲av无码片在线播放| 久久亚洲国产成人精品性色| 国产成人片无码视频在线观看| 精品国产熟女一区二区三区| 精品国产中文字幕在线| 望奎县| 香港特级三A毛片免费观看| A级毛片无码久久精品免费| 国产精品SM捆绑调教视频| 国产成人精品一区二三区| 黑人巨大亚洲一区二区久| 国产乱子伦视频在线播放| 嘉定区| 综合在线 亚洲 成人 欧美| 少妇又紧又色又爽又刺激视频| 亚洲欧美日韩综合一区在线| 美女裸体黄网站18禁止免费下载| 无码人妻一区二区三区兔费| 国产国产乱老熟女视频网站97 |