乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      C#中 As 和強(qiáng)制轉(zhuǎn)換的總結(jié)

       球球圓圓豆豆 2016-01-04

      1.1.1 摘要

      C#是一門強(qiáng)類型語言,一般情況下,我們最好避免將一個(gè)類型強(qiáng)制轉(zhuǎn)換為其他類型,但有些時(shí)候難免要進(jìn)行類型轉(zhuǎn)換。

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

      • 使用as操作符轉(zhuǎn)換,
      • 使用傳統(tǒng)C風(fēng)格的強(qiáng)制轉(zhuǎn)型
      • 使用is來做一個(gè)轉(zhuǎn)換測試,然后再使用as操作符或者強(qiáng)制轉(zhuǎn)

       

      1.1.2 正文

      正確的選擇應(yīng)該是盡可能地使用as操作符,因?yàn)樗葟?qiáng)制轉(zhuǎn)型要安全,而且在運(yùn)行時(shí)層面也有比較好的效率(注意的是as和is操作符都不執(zhí)行任何用戶自定義的轉(zhuǎn)換,只有當(dāng)運(yùn)行時(shí)類型與目標(biāo)轉(zhuǎn)換類型匹配時(shí),它們才會(huì)轉(zhuǎn)換成功)。

      現(xiàn)在我們通過一個(gè)簡單的例子說明as和強(qiáng)制轉(zhuǎn)換之間的區(qū)別,首先我們定義一間獲取不同類型對象的工廠,然后我們把未知類型轉(zhuǎn)換為自定義類型。

       

      復(fù)制代碼
      object o = Factory.GetObject();
      MyType t
      = o as MyType;
      if (t == null)
      {
      //轉(zhuǎn)換成功
      }
      else
      {
      //轉(zhuǎn)換失敗
      }


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

      }
      catch
      {
      ////異常處理
      }
      復(fù)制代碼

       

      通過上述代碼我們發(fā)現(xiàn)as類型轉(zhuǎn)換失敗時(shí)值為null不拋出異常,但強(qiáng)制轉(zhuǎn)換如果轉(zhuǎn)換失敗會(huì)拋出異常所以我們要添加異常處理。

      現(xiàn)在我們對as和強(qiáng)制轉(zhuǎn)換有了初步的了解,假設(shè)現(xiàn)在我們定義了一個(gè)抽象類Foo,然后Foo1繼承于它,并且再定義一個(gè)基類Logger,在Foo1中定義與Logger類型隱式轉(zhuǎn)換具體如下:

      復(fù)制代碼
      Foo1 myFoo; //// Inherits abstract class.
      Logger myFoo; //// base class.

      public class Foo1 : Foo
      {
      private Logger _value;

      /// <summary>
      /// 隱式自定義類型轉(zhuǎn)換。
      /// </summary>
      /// <param name="foo1"></param>
      /// <returns></returns>
      public static implicit operator Logger(Foo1 foo1)
      {
      return foo1._value;
      }
      }
      復(fù)制代碼

      現(xiàn)在我們猜猜看以下的類型轉(zhuǎn)換是否成功(提示:從編譯和運(yùn)行時(shí)類型轉(zhuǎn)換角度考慮)。

      復(fù)制代碼
      object myFoo = container.Resolve<Foo>(); //獲取未Foo1類型

      try
      {
      Logger myFoo1
      = (Logger)myFoo;
      if (myFoo1 != null)
      {
      Console.WriteLine(
      "Covert successful.");
      }
      }
      catch
      {
      Console.WriteLine(
      "Covert failed.");
      }
      復(fù)制代碼

      相信聰明的大家已經(jīng)想出答案了,激動(dòng)人心的時(shí)刻到了現(xiàn)在讓我們公布答案:轉(zhuǎn)換失敗拋出異常。

      圖1轉(zhuǎn)換失敗結(jié)果

       

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

      圖2編譯和運(yùn)行時(shí)自定義類型轉(zhuǎn)換

       

      通過上圖我們發(fā)現(xiàn)用戶自定義的轉(zhuǎn)換操作符只作用于對象的編譯時(shí)類型,而非運(yùn)行時(shí)類型上,OK現(xiàn)在讓修改一下代碼讓我們編譯器認(rèn)識(shí)自定義類型中。

      復(fù)制代碼
      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轉(zhuǎn)型為Foo1
      try
      {
      Logger myFoo1
      = (Logger)myFoo;
      if (myFoo1 != null)
      {
      Console.WriteLine(
      "Covert successful.");
      }
      }
      catch
      {
      Console.WriteLine(
      "Covert failed.");
      }

      Console.ReadKey();
      }
      復(fù)制代碼

      圖3轉(zhuǎn)換成功結(jié)果

       

      現(xiàn)在類型可以轉(zhuǎn)換成功,這是因?yàn)榫幾g器使用了我們自定義的隱式轉(zhuǎn)換,由于myFoo這次的編譯類型為Foo1,編譯器首先查找是否存在Foo1和Logger自定義轉(zhuǎn)換類型,由于我們定義了一種由Foo1到Logger的隱式類型轉(zhuǎn)換所以轉(zhuǎn)換成功。

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

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

      as不能用于值類型,這是因?yàn)橹殿愋筒荒転閚ull(注意:C#2.0中,微軟提供了Nullable類型,允許用它定義包含null值,即空值的數(shù)據(jù)類型)像這種情況我們應(yīng)該使用強(qiáng)制類型轉(zhuǎn)換。

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

      大家可以發(fā)現(xiàn)和我們之前使用的強(qiáng)制轉(zhuǎn)換類似,而且還有處理異常,現(xiàn)在修改一下我們代碼讓它更加簡潔實(shí)現(xiàn)如下:

      復(fù)制代碼
      object tempFoo = container.Resolve<Foo>(); //獲取未Foo1類型
      int i = 0; //值類型轉(zhuǎn)換
      if (tempFoo is int)
      {
      i
      = (int) tempFoo;
      }


      object tempFoo = container.Resolve<Foo>(); //獲取未Foo1類型
      Logger myFoo1 = null; //引用類型轉(zhuǎn)換
      if (tempFoo is Logger)
      {
      myFoo1
      = tempFoo as Logger;
      }
      復(fù)制代碼

      1.1.3 總結(jié)

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

      一般情況我們應(yīng)該先考慮使用as進(jìn)行類型轉(zhuǎn)換,然后再考慮使用is,最后才考慮使用強(qiáng)制轉(zhuǎn)換。

       

      as

      強(qiáng)制轉(zhuǎn)換

      轉(zhuǎn)換失敗是否拋出異常

      No

      Yes

      支持值類型和引用類型轉(zhuǎn)換

      只支持引用類型

      Yes

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多