2009-07-28 22 views
4

可能重複:
Casting: (NewType) vs. Object as NewType在c#中投射時應該使用(ObjectType)還是'作爲ObjectType'?

例如說我有一個類叫做MyObjectType,我想事件的sender參數轉換成這種類型。我通常會去它通過簡單地這樣做:

MyObjectType senderAsMyType = (MyObjectType) sender; 

最近我意識到,自己還可以做這樣的:

MyObjectType senderAsMyType = sender as MyObjectType; 

哪種方式是最有效的?這樣我可以使我的代碼保持一致並使用其中一種方式。或者他們都有專業和缺點?如果是這樣,請有人告訴我他們。

再次感謝,

+3

沒有人提到過一個重要的觀點,那就是鑄造和「as」不會做同樣的事情。例如,如果您有從Foo到Bar的用戶定義顯式轉換,則「(Bar)foo」將調用轉換方法,但「foo as Bar」_不是_。確保你選擇了實際做你想要的選項。把它弄清楚,然後說清楚,然後才考慮加快速度。 – 2009-07-28 16:36:01

回答

4

如果你想避免任何InvalidCastExceptions使用

MyObjectType senderAsMyType = sender as MyObjectType; 

以其它方式使用

MyObjectType senderAsMyType = (MyObjectType)sender; 

如果InvalidCastException代表應用程序中的真正的特殊情況。

至於性能,我會爭辯說,你會發現兩種不同類型的鑄件之間沒有明顯的差異。我興趣,雖然,所以我用Jon Skeet's BenchmarkHelper取得的結果證實了我的懷疑:

測試:

using System; 
using BenchmarkHelper; 

class Program 
{ 
    static void Main() 
    { 
     Object input = "test"; 
     String output = "test"; 

     var results = TestSuite.Create("Casting", input, output) 
      .Add(cast) 
      .Add(asCast) 
      .RunTests() 
      .ScaleByBest(ScalingMode.VaryDuration); 
     results.Display(ResultColumns.NameAndDuration | ResultColumns.Score, 
       results.FindBest()); 
    } 

    static String cast(Object o) 
    { 
     return (String)o; 
    } 

    static String asCast(Object o) 
    { 
     return o as String; 
    } 

} 

輸出:

============ Casting ============ 
cast 30.021 1.00 
asCast 30.153 1.00 
2

基本區別:如果sender不是MyObjectType或它的子類中的一個,第一個例子中(直接鑄造)的實例拋出異常;第二個(作爲運算符)返回null。

沒有一個是明顯好或壞;根據你目前面臨的情況,你應該使用這一個或另一個。如果sender不是MyObjectType你想要做什麼?或許,在這種情況下,因爲它是一個事件處理程序,引發異常是完全沒有問題......

0

您應該使用(MyObjectType)只要有可能,因爲你會得到一個異常立即如果轉換失敗。有了as,您可能會在稍後的任何地方得到NullRef-exception。
僅當您之後處理失敗的演員時才使用as

0

他們做的事情稍有不同。這取決於你想要什麼。

// Will throw an exception if the cast cannot be made 
MyObjectType foo = (MyObjectType)bar; 
您使用

// Will return null if the cast cannot be made 
MyObjectType foo = bar as MyObjectType; 

是你?如果您希望演員經常潛在失敗(並且您對此感到滿意),那麼可以嘗試as並在之後測試爲空,如果您希望演員永遠不會失敗,請轉至(type)

請記住,如果參考文獻可以是null無論如何,您也需要知道這一點,請在演員投入前測試null

0

不要過分擔心效率,最好根據語義做出決定。一個人是否比另一個人更有效率將取決於個人情況,以及你期望它失敗的次數。

直接投射「(ObjectType)」可能會失敗,並將引發InvalidCastException。

「as」不會因爲例外而失敗,但是如果轉換不起作用,將返回空對象。

如果演員陣容絕對有效,就做演員。這樣,如果事情出錯,你會得到例外,並希望能夠解決問題。

如果您不能確定對象類型的,它可以用「」有用,只是檢查空

0
MyObjectType senderAsMyType = (MyObjectType) sender; 

這將引發InvalidCastException如果發送者不能被轉換爲MyObjectType

MyObjectType senderAsMyType = sender as MyObjectType; 

senderAsMyTypenull如果發送者不能被轉換爲MyObject。該方法不能與值類型一起使用。

我相信後者速度稍快,但差異實際上並不重要。

+0

我認爲速度是非常主觀的,並會受到你期望的失敗百分比的影響。 – 2009-07-28 10:57:42

0

這取決於你對物體的期望。如果對象應該是那種類型的,你需要訪問對象的成員,使用方法:

MyObjectType senderAsMyType = (MyObjectType) sender; 

如前所述,如果它是無效的,這將引發一個InvalidCastException的

如果可能是這種類型的,你只需要採取行動,如果是,使用「爲」,並檢查空

MyObjectType senderAsMyType = sender as MyObjectType; 

if(senderAsMyType != null) 
{ 
    senderAsMyType.MyMethod() 
} 

但是如果你只檢查的類型,但不需要鄰bject,用「是」操作,因爲這將是最廉價的資源,智慧

if(sender is MyObjectType) 
    //do something 
0

從最佳實踐角度來看,如果你期望不同類型的對象,你應該使用as關鍵字,您的代碼可以處理它們,例如

public void MyFunction(MyObject obj) 
{ 
    obj.DoSomething(); 
    SpecializedObject specialized = obj as SpecializedObject; 
    if(specialized!=null) 
    { 
    specialized.DoSthSpecial(); 
    } 
} 

而且使用的時候你肯定的類型將是你所期望的正常轉換,你只需要施展它的,因爲技術方面的原因:

XmlSerializer xmlSerializer = new XmlSerializer(typeof(MyObject)); 
MyObject obj = (MyObject)xmlSerializer.Deserialize(xml); 

這樣它不僅速度更快,而且也不會隱藏錯誤。

相關問題