2009-07-28 2 views
4

可能性の重複:例えば
Casting: (NewType) vs. Object as NewTypeC#でキャストするときに(ObjectType)か 'ObjectType'を使うべきですか?

言って私はMyObjectTypeというクラスを持っていると私は、このタイプのイベントの送信元のパラメータを変換したいです。私は通常、単純にこれを行うことによって、それについて移動します:

MyObjectType senderAsMyType = (MyObjectType) sender; 
また次のように行うことができることを私は最近気付きました

MyObjectType senderAsMyType = sender as MyObjectType; 

を最も効率的であるどっち?私は自分のコードを一貫性のあるものにし、その中の一つの方法を使うことができます。それとも、どちらもプロとコンプを持っていますか?もしそうなら、誰かが私にそのことを知らせてもらえますか?あなたはInvalidCastExceptionは、アプリケーションの真の例外的な状況を表す場合はそうでない

MyObjectType senderAsMyType = (MyObjectType)sender; 

を使用するすべてのInvalidCastExceptions使用

MyObjectType senderAsMyType = sender as MyObjectType; 

を避けたい場合は

おかげで再び、

+3

誰も言及していない重要な点は、キャスティングと "as"は同じことをしないことです。たとえば、FooからBarへのユーザー定義の明示的な変換がある場合、 "(Bar)foo"は変換メソッドを呼び出しますが、 "foo as Bar"は変換しません。あなたが実際に望むことをするオプションを必ず選択してください。それを正しいものにして、それを明確にして、それをより速くすることを検討してください。 –

答えて

4

パフォーマンスに関しては、2つの異なる種類のキャストの間に目立つ違いがないと私は主張します。 I ので、私は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

私はこの答えは助けになると思います...

Casting: (NewType) vs. Object as NewType

+0

ああ申し訳ありませんが、私が検索したときに答えを見つけることができませんでした。ありがとう – ThePower

2

基本的な違い:senderMyObjectTypeまたはそのサブクラスの1つのインスタンスではない場合、最初の例(直接キャスト)は例外をスローします。 2番目の(演算子として)はnullを返します。

いずれも明らかに優れているか悪いですか。あなたは現時点で直面している状況に応じてどちらか一方を使うべきです。 senderMyObjectTypeではない場合はどうしますか?それはイベントハンドラなので、おそらく、この場合では、例外をスローすることは完全に罰金です...

0

キャストが失敗した場合は、すぐに例外が発生しますので、あなたは、(MyObjectType)可能な限りを使用する必要があります。 asでは、後でNullRef例外が発生することがあります。
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に行き、後でnullをテストしてください。失敗しないと思ったら(type)に行ってください。

参考資料がとにかくnullである場合は、キャストする前にnullをテストしてください。

0

効率についてあまり心配しないでください。セマンティクスに基づいて決定する方が良いです。 1つが他のものよりも効率的かどうかは、個々の状況に大きく左右され、何回失敗すると予想されます。

ストレートキャスト "(ObjectType)"が失敗し、InvalidCastExceptionがスローされます。

"as"は例外で失敗しませんが、代わりにキャストが機能しない場合はnullオブジェクトを返します。

キャストが間違いない場合は、キャストしてください。そうすれば、事態がうまくいかないと例外が発生し、問題を解決できるようになります。

あなたがオブジェクト型の特定されていない場合、それは「として」を使用することが有用であると送信者だけがMyObjectTypeにキャストできない場合、これはInvalidCastExceptionをスローしますヌル

0
MyObjectType senderAsMyType = (MyObjectType) sender; 

を確認することができます。

MyObjectType senderAsMyType = sender as MyObjectType; 

senderAsMyType送信者がMyObjectにキャストできない場合nullになります。このメソッドは値型では使用できません。

私は後者がわずかに速いと信じていますが、違いは事実上重要ではありません。

+0

私は速度が非常に主観的で、あなたが期待しているキャスト失敗の割合によって影響を受けると思います。 –

0

これは、オブジェクトの期待に応じて異なります。オブジェクトは、そのタイプのものでなければならない、とあなたはそれがメンバーにオブジェクトにアクセスする必要がある場合は、次のコマンドを使用します。前に述べたように、それ場合、それは無効

ある場合

MyObjectType senderAsMyType = (MyObjectType) sender; 

、これはあなたのためにInvalidCastExceptionがをスローしますそのタイプであること、そしてあなたはそれがある場合にアクションを取りたい「」として使用し、あなただけのタイプをチェックしているが、Oを必要としない場合はnullを

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); 

このようにそのないだけ速くはなく、エラーを隠すこともありません。

関連する問題