実際、override
これらの値には意味がありません。実際、オーバーライドの利点は、派生クラス自体を知らなくても、派生クラスのメソッドを呼び出すことができることです。
例えば :
static void Main()
{
NaturalFood food = GetSomeFood(); // At this point, we don't know the actual type
food.SomeMethodInBaseClass(); // ok
}
static NaturalFood GetSomeFood()
{
if(somecondition) {
return new Fruits();
}
else{
return new Vegetables();
}
}
public abstract class NaturalFood
{
public abstract void SomeMethodInBaseClass();
}
public class Fruits : NaturalFood
{
public override void SomeMethodInBaseClass(){
Console.WriteLine("I'm a fruit");
}
}
public class Vegetables : NaturalFood
{
public override void SomeMethodInBaseClass(){
Console.WriteLine("I'm a vegetable");
}
}
あなたが何をしたか想像できません。mainメソッドで、AllListを呼び出してみてください。
static void Main()
{
NaturalFood food = GetSomeFood(); // At this point, we don't know the actual type
food.SomeMethodInBaseClass(); // ok
food.AllList.XXXX; // What? it won't compile
}
これはコンパイルされません。コンパイラーには、使用可能な列挙値を推測するための実際の派生クラスを知る方法がありません。
ただし、基本タイプから列挙を削除すると、これは機能します。
static void Main()
{
NaturalFood food = GetSomeFood(); // At this point, we don't know the actual type
food.SomeMethodInBaseClass(); // ok
Fruits f = new Fruits();
Console.WriteLine( f.AllList.Apple); // Ok
Vegetable v = new Vegetable ();
Console.WriteLine( v.AllList.Potatoe); // Ok
}
しかし、ご覧のとおり、実際の型を明示的に知る必要があるため、多型を役に立たなくします。
[編集] 2回目の編集に答えるのは難しいです。実際、そのような制約を検証する方法はたくさんあります。これ以上の文脈がなければ、答えるのは難しいかもしれません。私が考える最も簡単な方法は、どの種類の列挙が受け入れられるかを説明するオーバーライドされたプロパティを各派生クラスに追加することです。
public enum NaturalFoodType {
Unknown = 0,
Apple= 1,
Banana = 2,
Potatoe = 3,
Cucumber = 4
}
public abstract class NaturalFood
{
public abstract void SomeMethodInBaseClass();
public abstract IEnumerable<NaturalFoodType> AcceptedFoodType { get; }
public bool IsValid(NaturalFoodType type){
return AcceptedFootType.Contains(type);
}
}
public class Fruits : NaturalFood
{
public override void SomeMethodInBaseClass(){
Console.WriteLine("I'm a fruit");
}
public override NaturalFoodType {
get {
yield return NaturalFoodType.Apple;
yield return NaturalFoodType.Banana;
}
}
}
public class Vegetables : NaturalFood
{
public override void SomeMethodInBaseClass(){
Console.WriteLine("I'm a vegetable");
}
public override NaturalFoodType {
get {
yield return NaturalFoodType.Potatoe;
yield return NaturalFoodType.Cucumber;
}
}
}
しかし、正直なところ、それは多くの配管コードを追加し始め、それはかなり読めなくなります。許容できる解決策を見つけるには、より高い範囲で問題を検討する必要があります。