私はC#のジェネリックスを理解するための簡単なコードを試しています。ここでのコードの目的は、自分の動物を持ち、さまざまなことをするように頼むトレーナー(例のために、ジャンプする)を持つことです。継承したクラスを継承する
問題は、トレーナーのコンストラクターにあります。私は犬、または猫を渡すことができるようにしたいと思います。彼らはどちらも同じクラスから継承しますが、型定義を指定したため、引数として渡すことはできないようですが、どちらも有効ではありません。 「動物」のようなジェネリッククラスを指定する方法があるので、犬や猫を渡してメンバーにしておくことができますか?
class AnimalDefinition
{
public Fur Fur;
}
class DogDefinition : AnimalDefinition
{
public BarkSound Bark;
}
class CatDefinition : AnimalDefinition
{
public MeowSound Meow;
}
class Animal<TDefinition> where TDefinition : AnimalDefinition
{
public TDefinition Definition;
public void Jump()
{
Console.WriteLine("Jump.");
}
}
class Dog : Animal<DogDefinition>
{
public Dog(DogDefinition def)
{
Definition = def;
}
}
class Cat : Animal<CatDefinition>
{
public Cat(CatDefinition def)
{
Definition = def;
}
}
class Trainer
{
Animal _animal;
public Trainer(Animal myAnimal)
{
_animal = myAnimal;
}
public MakeJump()
{
_animal.Jump();
}
public Listen()
{
// if T is DogDefinition hear barking
// else if T is CatDefinition hear a meowing, etc
}
}
EDIT:Chris Bergerの回答(動作しますが、私は質問/回答論理を維持するためのコードを変更していません)に続く追加質問です。私はAnimalクラスに定義メンバーを追加しました。 Trainerクラスの中からBarkやMeowにアクセスする方法はありますか?または、TrainerクラスをCatTrainer : Trainer<CatDefinition>
で派生させなければなりませんか?つまり、私たちはクラスで持っているものに似たものがある、
if(T is CatDefinition)
{ // Meowing}
else
{}
:
ここでは、そのパターンにもう少し読みます。 – SLaks
「追加の」シナリオで何をしたいのかよくわからないし、2番目の質問をするために質問を編集するのは一般的にスタックオーバーフローの悪い考えだと思うが... 私はそれだと思う'if(T is CatDefinition){((Animal)_ myAnimal).Meow();のようなことをすることで可能です。 } ' これらのクラスの定義方法によります。私はそれがカプセル化の違反であると考えています。だから理想的にはそれを回避するより良い方法を見つけるでしょう。 –