2009-06-07 17 views
1

インタフェース:
インタフェースIPlay < T > {}ジェネリック型内キャスト問題が、同じタイプ

クラス:
クラスMp3Player:IPlay < INT > {}
クラスOggPlayer。 IPlay < double > {}
class DummyPlayer:IPlay <オブジェクト> {}使用しようとする


1 IPlay <オブジェクト>プレーヤー=新しいMp3Player()。
2. IPlay < int > player2 = new OggPlayer();

Aビッグ1と2の用途はなぜキャストできないのですか?
int to object、またはintをdoubleにします。それはノンネリックなケースで可能です。他の方法はありますか?

+0

それは*正確な*の重複はありませんが、私はこの質問には、すべてのコに非常に近いので、そこに/ contravarianceの質問を閉じるために投票しています。いくつかの議論のためにこれをチェックしてください:http://stackoverflow.com/questions/6557/in-c-why-cant-a-liststring-object-be-stored-in-a-listobject-variable –

答えて

4

無効なキャストを実行しようとしています。 Mp3PlayerはIPlay <オブジェクトではありません。>、IPlay <int>です。あなたのOggPlayerはIPlay <double>であり、IPlayではなく<int>です。 IPlay <int>をIPlay <オブジェクト>またはIPlay <double> IPlay <int>に変換することはできません。彼らはお互いから継承しないし、彼らは一般的なので、彼らはお互いに強く区別される明確なタイプです。

C#4.0では、このような暗黙的なキャストは、改善された共同/コントラストの差異によって可能になる可能性があります。しかし、一般的に言えば、異なるタイプの境界を越えたそのような暗黙のキャストは不可能です。

2

あなたが探しているのはcovarianceと呼ばれ、この機能はインターフェイスタイプのC#4でサポートされます。

3

想像:

interface IPlay<T> 
{ 
    T GetSomething(); 
    DoSomething(T value); 
} 

をので、使用している場合:次に

IPlay<object> player = new Mp3Player(); 

GetSomething()は安全型であってもよいが、方法についてのDoSomething(object value)? ...その呼び出しは、オブジェクトがintを期待しているので、ロジックがオブジェクト上で動作することを保証できません。

.NET 4にはインターフェイスの分散を示すメカニズムがあるので、少なくとも最初の割り当てが機能する場合は、Tを戻り値として使用するようにインターフェイスをマークすることができます。

ただし、doubleintの間に継承関係がないため、2番目の(IPlay<int> player2)は機能しません。暗黙的に値をキャストできることは、継承と同じではありません。彼は共同/ contravarianceは、(とりわけ)C#4.0で動作する方法を説明しますPDCからのアンダース・ヘルスバーグによって

0

IPlay<T>が共通の祖先を生成するというよくある誤解があります(IPlay<object>)。これは価値があるかもしれませんが、それは真実ではありません。

あなたは自分自身を生成し、共通の祖先に名前を付ける必要があります。

interface IPlay {} 
interface IPlay<T> : IPlay {} 
関連する問題