一般的な基本クラスはどうですか?
public class Poo { }
public class RadioactivePoo : Poo { }
public class BaseAnimal<PooType>
where PooType : Poo, new() {
PooType Excrement {
get { return new PooType(); }
}
}
public class Dog : BaseAnimal<Poo> { }
public class Cat : BaseAnimal<RadioactivePoo> { }
編集:拡張メソッドとマーカーインターフェイスを使用した新しいソリューション...
public class Poo { }
public class RadioactivePoo : Poo { }
// just a marker interface, to get the poo type
public interface IPooProvider<PooType> { }
// Extension method to get the correct type of excrement
public static class IPooProviderExtension {
public static PooType StronglyTypedExcrement<PooType>(
this IPooProvider<PooType> iPooProvider)
where PooType : Poo {
BaseAnimal animal = iPooProvider as BaseAnimal;
if (null == animal) {
throw new InvalidArgumentException("iPooProvider must be a BaseAnimal.");
}
return (PooType)animal.Excrement;
}
}
public class BaseAnimal {
public virtual Poo Excrement {
get { return new Poo(); }
}
}
public class Dog : BaseAnimal, IPooProvider<Poo> { }
public class Cat : BaseAnimal, IPooProvider<RadioactivePoo> {
public override Poo Excrement {
get { return new RadioactivePoo(); }
}
}
class Program {
static void Main(string[] args) {
Dog dog = new Dog();
Poo dogPoo = dog.Excrement;
Cat cat = new Cat();
RadioactivePoo catPoo = cat.StronglyTypedExcrement();
}
}
このように、DogとCatは両方ともAnimalから継承します(コメントで述べたように、私の最初のソリューションは継承を保持しませんでした)。
マーカーインターフェイスでクラスを明示的にマークする必要がありますが、これは面倒ですが、おそらくこれはあなたにいくつかのアイデアを与える可能性があります...
2番目の編集@Svish:コードを変更して、拡張メソッドがiPooProvider
から継承するという事実を強制していないことを明示的に示しましたBaseAnimal
。「さらに強く型付けされた」とはどういう意味ですか?