2017-02-09 23 views
0

私はいくつかの助けが必要です。それはかなり簡単です。私はこのコードを手に入れました。正しいかどうか、あるいはより良いやり方を提案したい場合は、議論したいと思います。私は答えについて考えていますが、あなたの答えを見たいと思います。それは内にある場合ので、nullであると#とのキャスティング

(ClassB)myObjectB.MethodJustInB(); 

をし、それをチェックする必要はありません。ここでは、私はちょうどやって、後にすべての場合は、新しいオブジェクトを作成する必要がないと思います

if (myObject is ClassA) 
{ 
    var myObjectA = myObject as ClassA; 
    myObjectA?.MethodJustInA(); 
} 
else if (myObject is ClassB) 
{ 
    var myObjectB = myObject as ClassB; 
    myObjectB?.MethodJustInB(); 
    myObjectB?.OtherMethodJustInB(); 
} 

を行きます

おかげ

+5

あなたは 'as'を必要としませんすでにタイプをチェックしている場合は、直接キャストできます。ここでは不可能なキャストが失敗する可能性がある場合、 'as '演算子は便利です。 –

+1

*既存のオブジェクトをキャストしていない新しいオブジェクト*を作成する必要はありません。それらは参照型であるため、変更可能です – Liam

+0

@TimSchmelterそうでないのは悪いですか?同様に、私は '(ClassA)myObject.MethodJustInB();'または '(myObject as ClassB).MethodJustInB();'のようにすることができます。その場合の違いは何ですか? – Cataklysim

答えて

2

私はasでキャストしてnullをチェックすることを好む、あなたはをスキップすることができ、このようnullではないためである場合チェック。また、オブジェクトがnullでないことがわかっているため、elvis演算子?.は必要ありません。

var myObjectA = myObject as ClassA; 
var myObjectB = myObject as ClassB; 
if (myObjectA != null) 
{ 
    myObjectA.MethodJustInA(); 
} 
else if (myObjectB != null) 
{ 
    myObjectB.MethodJustInB(); 
    myObjectB.OtherMethodJustInB(); 
} 
+3

私が経験したことは、チェックする可能性のあるタイプが複数ある場合は、かなり面倒ですが、一般的には良い解決策です。 –

+0

はい、このパターンでは、if-else以外のスコープに不要なキャストや変数が存在する可能性があります。たとえば、最初の 'if'がtrueと評価された場合、ClassBへのキャストは必要ありません。 –

+0

確かに、2番目のキャストを 'else'に移動することはできますが、ネストされた' if..else'ブロックで無限に終わる可能性があります。 –

3

いくつかの最適化が可能です。

  • myObject is ClassAの場合、ソフトキャストは必要ありません。代わりに、キャストを直接行うことができます:var myObjectA = (ClassA)myObject;
  • この場合、単一のメソッドを呼び出すだけで、新しい変数を割り当てる必要はありません:((ClassA)myObject)?.MethodJustInA();
  • は、myObjectがnullの場合にfalseと評価されるため、再度チェックする必要はありません。((ClassA)myObject).MethodJustInA();
  • だから、

:あなたがいる場合

((ClassB)myObject).MethodJustInB(); 
+0

しかし、 'is'を使ってオブジェクトを型にキャストしようとすると、' is'が 'true'を返す条件の後に2回目のキャストが必要です。 'as'を使い、' null'をチェックする方が良いでしょう - この場合は時間だけをキャストします。 –

+1

@Roma "使用しているときにオブジェクトをある型にキャストしようとしています">そうではありません。型のテストは、キャストや割り当てよりはるかに簡単です。 –

+1

http://stackoverflow.com/questions/686412/c-sharp-is-operator-performance/686431#686431彼らは、実際には、同じことをやっていると言っています。 、Konrad Rudolphによるコメントを参照してください。 – HimBromBeere

0

複数のタイプをテストする場合は、as + nullチェックがあり、より効率的(ワンキャスト、代わりのis +キャスト):

与えられたシナリオで
var a = myObject as ClassA; 
if (a != null) 
    a.MethodJustInA(); 
var b = myObject as ClassB; 
if (b != null) 
    b.MethodJustInB(); 

私もこの

{ 
    var obj = myObject as ClassA; 
    if (obj != null) 
     obj.MethodJustInA(); 
} 
{ 
    var obj = myObject as ClassB; 
    if (obj != null) 
     obj.MethodJustInB(); 
} 

{ }などのローカルスコープがすることを可能に作ると思います同じ変数名を再利用する(コピー/貼り付けが簡単で、私の意見では読みやすい)。


私はビットrushyだったと(あなたがbなどとして、それをキャストしたくないmyObject is ClassA)だけでなくについてelseケースを考えていません。通常は、ifとそれに対応するメソッド呼び出しが成功するたびにreturnを実行します。そうでなければ私はいい外観のif/else ifコードを構築することができません。、ClassBClassAを継承している場合:

(myObject as ClassA)?.MethodJustInA(); 
(myObject as ClassB)?.MethodJustInB(); 

本当にきれいに見えますが、それは不必要Bにキャストするんだろうと副作用があります。


もう一つのアイデアは、C#6.0のヌル条件演算子を使用することです両方のメソッドは両方ともキャストが成功するため、と呼びます。

注:前述の副作用は残念ながら、すべてのスニペットに適用されます。

1

var myObjectB = (ClassB)myObject; 

またはそれを直接キャスト:あなたはこのようなあなたのオブジェクトをキャストすることができ、それらのif文の中で

if (myObject is ClassA) 
{ 
    ((ClassA)myObject).MethodJustInA(); 
} 
else if (myObject is ClassB) 
{ 
    var myObjectB = (ClassB)myObject; 
    myObjectB.MethodJustInB(); 
    myObjectB.OtherMethodJustInB(); 
} 
+0

ローカルスコープは、 'ClassB'が' ClassA'を派生させたときに問題を引き起こすかもしれません。 –

+0

@PatrickHofman、 'OP'は' else if'を使います(彼の場合はそれも問題になります)。しかしあなたは正しいですし、editも見てください。私の答えは最高ではありませんが、私はあなたも理想だとは思わない) – Sinatr

+0

@PatrickHofman、お待ちください。うん、今私はそれを参照してください。 – Sinatr

0

あなたはこのようにそれを使用している場合、あなたはそれだけにものをキャストする必要があります。

var myObjectA = (myObject as ClassA); 

if (myObjectA != null) 
{ 
    myObjectA.MethodJustInA(); 
} 
else 
{ 
    var myObjectB = (myObject as ClassB); 

    if (myObjectB != null) 
    { 
     myObjectB.MethodJustInB(); 
    } 
} 

そして、あなたが行うことができますC#7.0で:

if (myObject is ClassA myObjectA) 
    myObjectA.MethodJustInA(); 
else 
    if (myObject is ClassB myObjectB) 
     myObjectB.MethodJustInB(); 
+0

'(myObject as ClassA)?MethodJustInA();' if文なしでコードを変更できます –

+1

C#7.0は、このケースに最適なソリューションを提供します。それが生きるまで待つことはできません。 – Sinatr

関連する問題