如何在c#中拥有一种虚拟静态成员?

本文关键字:一种 虚拟 静态成员 拥有 | 更新日期: 2023-09-27 18:10:51

我有一个类:

public class Food
{
  public static IList<Ingredient> ingredients
  public bool uses(Ingredient i)
  {
    return ingredients.Contains(i);
  }
}

然后我继承它做各种各样的食物,像:

public class Cake : public Food
{
  public static IList<Ingredient> ingredients = new List<Ingredient>()
  {
    Sugar,
    Eggs,
    Milk
  }
}

现在我希望能够执行

Food f = getFood();
if (f.uses(Eggs))
{
   // Do something
}

所以我想有一个静态的成分列表,例如,所有蛋糕都可以共享,而不是每个蛋糕实例的列表,并能够以虚拟的方式访问它。

如果需要的话,我愿意搅动代码以获得类似的效果!

如何在c#中拥有一种虚拟静态成员?

在这种情况下,OOD"倾向于"使类Food抽象,因为"成分"将不同于Food到另一个。因此,正如其他人指出的那样,使这个列表static是没有意义的,因为static应该是一个属性的修饰符,该属性不受对象的区分。

我的建议如下:

public abstract class Food
{
   public abstract IList<Ingredient> Ingredients
   {
       get;
   }
}

现在任何类——具体的——将从Food驱动,因此它必须实现这个属性,以便它给出自己的ingredients:

public class Cake : Food
{
  public override IList<Ingredient> Ingredients
  {
      get { 
              return new IList<Ingredient>()
              { Sugar, Eggs, Milk };
          }
  }
}

你可以定义一个方法GetIngredients()让子类覆盖:

public abstract class Food
{
  public static IList<Ingredient> ingredients
  public bool uses(Ingredient i)
  {
    return GetIngredients().Contains(i);
  }
  protected abstract IList<Ingredient> GetIngredients();
}

public class Cake : public Food
{
  public static IList<Ingredient> ingredients = new List<Ingredient>()
  {
    Sugar,
    Eggs,
    Milk
  }
   protected override IList<Ingredient> GetIngredients()
   {
      return ingredients ;
   }
}

把所有这些实例都变成一个类怎么样?如:

class Food
{
    public IList<Ingredient> ingredients;
    public Food(IList<Ingredient> ingredients)
    {
        this.ingredients = ingredients.Clone();
    }
    public bool uses(Ingredient i)
    {
        return ingredients.Contains(i);
    }
}
Food Cake = new Food({ Sugar, Eggs, Milk });

这些成分不需要是静态的。您可以从Cake类派生出所有类型的蛋糕,这样它们就继承了共同的成分:

public class Cake : Food 
{ 
  public IList<Ingredient> ingredients = new List<Ingredient>() 
  { 
    Sugar, 
    Eggs, 
    Milk 
  } 
} 

public class DevilsFoodCake : Cake 
{ 
  public DevilsFoodCake()
  {
        ingredients.AddRange(new List<Ingredient>() 
        { 
            Chocolate,
            SourCream
        } 
   }
} 

如果您的目标是每个类型有一个成分集合,那么您就不能真正做到这一点。我认为你能做的最好的事情,虽然不是我不推荐的,是把负责任的移动到另一个类,像这样:

public class IngredientStore
{
    public static IngredientStore Current
    {
        get;
        private set;
    }
    private Dictionary<Type, List<Ingredient>> ingredients = new Dictionary<Type, List<Ingredient>>();
    static IngredientStore()
    {
        Current = new IngredientStore();
    }
    public void Register(Type type, List<Ingredient> ingredients)
    {
        this.ingredients[type] = ingredients;
    }
    public bool Uses(Type type, Ingredient ingredient)
    {
        // TODO: check the type is registered
        return this.ingredients[type].Contains(ingredient);
    }
}
public class Food
{
    public bool Uses(Ingredient ingredient)
    {
        return IngredientStore.Current.Uses(this.GetType(), ingredient);
    }
}
public class Cake : Food
{
    static Cake()
    {
        IngredientStore.Register(typeof(Cake), new List<Ingredient>
        {
            Ingredient.Butter,
            Ingredient.Eggs,
            Ingredient.Flour,
        };
    }
}
public class CherryCake : Cake
{
    static CherryCake()
    {
        IngredientStore.Register(typeof(CherryCake), new List<Ingredient>
        {
            Ingredient.Butter,
            Ingredient.Eggs,
            Ingredient.Flour,
            Ingredient.Cherries,
        };
    }
}