6

ジェネリック型のキャストに問題があります。

たとえば、私はクラスを持っています:

public class Dog
{
}

public class Husky : Dog
{

}

public class MyWrapper<T> where T : class
{
}

そして、私はこのようなことをしたいのですが、方法がわかりません

MyWrapper<Husky> husky = new MyWrapper<Husky>();
List<MyWrapper<Dog>> dogs= new List<MyWrapper<Dog>>();
dogs.Add(husky); // how to cast husky to MyWrapper<Dog>?

編集: に変更Animal<T>されMyWrapper<T>たので、より適切な例になります

4

5 に答える 5

8

C# 4 以降では、インターフェイスの一般的な共分散を使用できます。そのためには、共変インターフェースを ( を使用してout)定義し、MyWrapperそのインターフェースを実装する必要があります。

public class Dog 
{
}

public class Husky : Dog
{
}

public class MyWrapper<T> : IMyWrapper<T> where T : class
{
}

public interface IMyWrapper<out T> where T : class
{
}

次に、これを行うことができます:

var husky = new MyWrapper<Husky>();
var dogs = new List<IMyWrapper<Dog>>();
dogs.Add(husky);
于 2013-01-23T09:11:55.220 に答える
7

残念ながらできません - はHuskyですが、DogAnimal<Husky>はありませんAnimal<Dog>

同様の質問については、.NET Casting Generic Listを参照してください。

于 2013-01-23T09:03:01.010 に答える
6

クラスの継承を次のように配置しない理由はありますか? Animal が型パラメーターを受け入れる必要がある理由がわかりません。

public abstract class Animal
{
}

public class Dog : Animal
{
}

public class Husky : Dog 
{
}
于 2013-01-23T09:03:39.117 に答える
5

そのためには共分散が必要です-ジェネリック型をアップキャストします-。

ただし、C#共分散は次の場合にのみサポートされます。

  • 代表者。
  • インターフェース。

そのため、私は解決策を見つけるだけです:マーカーインターフェイスを作成しますIAnimal<T>

public class Dog
{
}

public class Husky : Dog
{

}

public interface IAnimal<out T>
    where T : class
{
}

public class Animal<T> : IAnimal<T> where T : class
{
}

そして今、これは機能します:

        List<IAnimal<Dog>> list = new List<IAnimal<Dog>>();
        list.Add(new Animal<Husky>());

MSDNで共変性と反変性の詳細を確認してください。

アップデート

とにかく...一般的な制約のポイントは何T : classですか?あなたはTそれがクラスであることを知っているだけですが、それはパブリックコンストラクターを持たない可能性があります、またはそれは犬の代わりに岩である可能性があります、誰が知っていますか?

または、このクラス階層のポイントは何ですか?他の人が彼らの答えで指摘しているように、あなたの階層はあまりオブジェクト指向ではありません:犬は動物なのでDog 派生し Animalます。

これを変更するだけで、ジェネリック型パラメーターを使用する必要がなくなります。

継承よりもコンポジションを好むかもしれませんが、私はこの質問で何が最善かを決める傾向があります。

  • 特殊タイプといえば「BはA」と言えますか?=>次に、継承を選択します

  • 特殊なタイプについて言えば、「BはAの一部です」と言えますか=>次に、構成を選択します。

実際、共分散はあなたの質問を解決すると信じていますが、それはこの言語機能の間違ったユースケースだと思います。

于 2013-01-23T09:14:59.097 に答える
2

Animal<Husky>から派生していませんAnimal<Dog>

于 2013-01-23T09:08:25.130 に答える