5

以下のコードを考えると:

class Animal
{ }

class Dog : Animal
{ }

class Cage<T>
{
    private T animal;

    public Cage(T animal)
    {
        this.animal = animal;
    }

    public T Animal
    { 
        get { return animal;} 
    }
}

class Program
{
    static void Main(string[] args)
    {
        Dog dog = new Dog();
        Cage<Animal> animalCage = new Cage<Animal>(dog);
        Cage<Dog> dogCage = (Cage<Dog>)animalCage;
    }
}

最後のコンパイラ エラー (animalCage から dogCage への変換) を回避するにはどうすればよいですか?

私のコードでは、ケージに dogが含まれていることはわかっていますが、それにキャストする方法を見つけることができません。コンバーターを作成し、 Cage<Animal>の値から新しいCage<Dog>インスタンスを作成するための私のユニークな代替手段はありますか?

4

3 に答える 3

4

問題#1:Cage<Animal>インスタンスをインスタンスに変換することはできません。参照がより具体的でないタイプの変数に格納されているインスタンス(またはより具体的なタイプのインスタンスCage<Dog>)が必要です。Cage<Dog>

変化する

Cage<Animal> animalCage = new Cage<Animal>(dog);
Cage<Dog> dogCage = (Cage<Dog>)animalCage;

Cage<Animal> animalCage = new Cage<Dog>(dog);
Cage<Dog> dogCage = (Cage<Dog>)animalCage;

問題#2:クラスは共変性/反変性をサポートしていないため、Cage<Dog>インスタンスへの参照を変数に格納できません。Cage<Animal>

変化する

class Cage<T>
{
    ...

interface ICage<out T> 
{
    T Animal { get; }
}

class Cage<T> : ICage<T> 
{

Cage<Animal> animalCage = new Cage<Dog>(dog);
Cage<Dog> dogCage = (Cage<Dog>)animalCage;

ICage<Animal> animalCage = new Cage<Dog>(dog);
ICage<Dog> dogCage = (Cage<Dog>)animalCage;

その後、それは動作します。new Cage<Animal>(に変更しない場合new Cage<Dog>、実行時にキャスト例外が発生します。)

于 2012-10-26T23:04:46.513 に答える
2

Tこれは、通常は共変である必要があり(出力であるため)、反変の方法で使用しようとしていることを除いて、一般的な分散の仕事です。また、差異はクラスには適用されず、インターフェイスとデリゲートにのみ適用されるため、 を定義する必要がありますICage<T>

共分散により、他の方向へのキャストが可能になります: にキャストできICage<Dog>ますICage<Animal>Cage<Animal>aを含む aCatを aにキャストして、型が正しくないCage<Dog>レンダリングを試みることができるため、反変性は矛盾につながりますget_Animal

配列も共変です。 aDog[]を anにキャストできますが、犬だけが含まれていることがわかっていても、 anを a にAnimal[]キャストすることはできません。Animal[]Dog[]

次に考えたのは、明示的な変換演算子を定義することでしたが、これらはジェネリックにすることはできません

最後に、これを機能させるには new を作成する必要がありますCage<Dog>

于 2012-10-26T22:59:41.867 に答える
0

一般的な制約を追加できます

class Cage<T> where T : Animal

そして、メソッドから基本クラスを返すだけです

public Animal Animal
{ 
    get { return animal;} 
}

ジェネリック制約は、 Tに指定できる型に制限があることをコンパイラに通知します。など、何か他のものを指定Cage<object>すると、コンパイル時エラーが発生します。

于 2012-10-26T22:52:59.927 に答える