麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 學院 > 開發設計 > 正文

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

2019-11-17 03:35:13
字體:
來源:轉載
供稿:網友

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
= o as MyType;
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


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 欧美一区二区三区免费观看 | 一区二区三区欧美在线观看 | 国产精品一区二av18款 | 久久精品视频首页 | 成年免费网站 | 亚洲免费观看视频 | 婷婷久久网 | www.热 | 热久久成人 | 亚洲精品v天堂中文字幕 | 性生活视频软件 | 国产91精品久久久 | 亚洲男人的天堂在线视频 | 成年人激情在线 | xxxxxx视频| 在线小视频国产 | 久久免费视频精品 | 日韩视频在线观看免费 | 国内精品免费一区二区2001 | 美国黄色毛片女人性生活片 | 亚洲一区二区三区高清视频 | www.9191.com| 欧美一级黄色影院 | 日韩视频一区 | 久久久成人999亚洲区美女 | 欧美一级视频免费看 | 操你啦免费视频 | 99精品视频网站 | 日韩剧情片| 亚洲欧美国产高清 | 国产精品成人一区二区三区吃奶 | 一区二区久久精品66国产精品 | 欧美一级特黄特色大片免费 | 黄色大片网站在线观看 | 国产1级视频 | 欧美亚洲国产成人综合在线 | 成人男女啪啪免费观看网站四虎 | 国产精品91久久久 | 中文字幕在线观看1 | 午夜精品影院 | a视频在线免费观看 |