web-dev-qa-db-ja.com

具体的な実装オブジェクトにインターフェースをキャストしますか?

C#で、インターフェイスといくつかの具体的な実装がある場合、インターフェイスを具象型にキャストできますか、または具象型がインターフェイスにキャストできますか?

この場合のルールは何ですか?

37
GurdeepS

Java and C#。ダウンキャストには明示的なキャストが必要であり、オブジェクトが正しい型でない場合は例外をスローすることがあります。ただし、アップキャストには明示的なキャストは不要で、常に安全です。する。

つまり、_public interface Animal_と、このinterfaceCatおよびDog....の2つの実装があると仮定します。

_Animal meowAnimal = new Cat();  // No cast required
Animal barkAnimal = new Dog();  // No cast required

Cat myCat = (Cat) meowAnimal; // Explicit cast needed
Dog myDog = (Dog) barkAnimal; // Explicit cast needed

Dog myPet = (Dog) meowAnimal; // Will compile but throws an Exception
_

明示的なキャストの周りにtry/catchが必要になります。 C#には、便利なasキーワードがあります。

_Dog myDog = barkAnimal as Dog;
Dog myPet = meowAnimal as Dog;
_

例外はスローされず、myDogはnonNullになり、myPetはnullになります。 Javaには同等のキーワードはありませんが、型の安全性を保つために常にif (meowAnimal instanceof Dog)テストを使用できます。(「as」キーワードは、 ifを行うバイトコード、isのnullの割り当ては失敗します。しかし、おそらく.NETには、 "as"と同等のバイトコード命令があります。)

46
Eddie

ほとんどの言語では、両方向にキャストできます。具象クラスがある場合は、それをインターフェースにキャストできます。インターフェイスがある場合、具象クラスにキャストできます。

一般的に、最初の方向にのみ行きたいです。その理由は、インターフェイスへのポインタしか持っていない場合、具象クラスが何なのかを知らないからです。インターフェイスとして何かを渡す場合、そのインターフェイスから必要なことは何でもできるはずです。インターフェース上にない具体的なオブジェクトの一部を使用する必要がある場合は、キャストする代わりに修正する必要がある設計上の問題があります。

14
Steve Rowe

Java(ただし、他の言語のルールも同様です)について話している場合、次のようになります。

実際にキャストした参照が特定の具体的な実装への参照である場合、具体的な実装へのインターフェイスを(ダウン)キャストできます。つまり

Vehicle v=new Car();
(Car)v // this is OK
(Bus)v // this is not

エラーは、JavaでClassCastExceptionとして現れます。

インターフェイスの具体的な実装をインターフェイスに自由にアップキャストできます。

3
jpalecek

論理的なキャストであることを考えると、両方とも有効です。多くの場合、インターフェイスコンシューマは具象クラスにアクセスできません。これは、そもそもインターフェイスを使用する主な理由の1つです。

0
BC.

インターフェースcanクラス全体ですが、する必要はありません beであれば、インターフェースをパラメーターとして受け入れ、設定をコピーするコンストラクターを作成する方が良いでしょう。これにより、何が発生し、何が必要かを制御できます。

0