私はC#4.0のジェネリックと忙しかった、そして今、私は基本的にこのような何かをしたい:C# - ジェネリックコレクションをキャストする方法はありますか?
public abstract class GenericTree<T> : Tree
where T : Fruit
{
public Tree(IFruitCollection<T> fruits)
: base(fruits) { }
}
基本Treeクラスは次のようになります。ここでは
public abstract class Tree
{
private IFruitCollection<Fruit> fruits;
public IFruitCollection<Fruit> GetFruits
{
get { return fruits; }
}
public Tree(IFruitCollection<Fruit> fruits)
{
this.fruits = fruits;
}
}
は私の最初の問題です。 GenericTreeのコンストラクタは、ジェネリックコレクションをフルコレクションにキャストできません。私もGenericTreeの実装を持っています:
public class AppleTree : GenericTree<Apple>
{
public AppleTree()
: base(new FruitCollection<Apple>) { }
}
ここに私の2番目の問題があります。 myAppleTree.GetFruits.Add(...)を使用してAppleTreeのインスタンスに果物を追加するとき、私はリンゴだけに限定されません。私はあらゆる種類の果物を加えることが許されています。私はこれを望んでいない。
私はGenericTreeにこれを追加することで問題を解決しようとした:
new public IFruitCollection<T> GetFruits
{
get { return base.GetFruits as IFruitCollection<T>; }
}
しかし、これはどちらかのことはできません。それはどういうわけか常にnullを返します。私の最初の問題が解決されると、これが解決される可能性があります。
IFruitCollectionインターフェイスは次のようになります。
public interface IFruitCollection<T> : ICollection<T>
where T : Fruit { ... }
そしてFruitCollectionクラスは、コレクションクラスの簡単な実装です。 もちろん、AppleクラスはFruitクラスを拡張しています。
解決策は、IFruitCollectionインターフェイスを共分散と反共分散の両方に対応させることです。しかし、私はこれをどのように達成するのですか? "in"または "out"パラメータキーワードは、ICollectionインターフェイスでは許可されていないため、使用できません。
ありがとうございました!あなたのコメントを受けて
これは簡単に一つにツリーとGenericTreeクラスをマージすることで解決することができることに注意してください。しかし、これは私の問題の一例に過ぎないことを忘れないでください。自分のアプリケーションはもう少し複雑です。 –
あなたが示唆するように、解決策はTreeを汎用的にすることです。また、これは不可能であることを暗示します。何故なの? – phoog
ある時点で、私は木のリストが必要です。ツリーのリストは、ツリーのインスタンスを追加できないため、それを行いません。 Tree とツリーの間に暗黙的な参照がないことは言うまでもないでしょう。 –