Как я могу иметь своего рода виртуальный статический член в C # - PullRequest
2 голосов
/ 09 октября 2011

У меня есть класс, подобный:

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
}

Итак, я хочу иметь статический список ингредиентов, которые (например) могут использовать все торты, а не список для каждого торта и иметь доступ к нему виртуальным способом.

Я готов поменять код, чтобы получить аналогичный эффект, если нужно!

Ответы [ 5 ]

4 голосов
/ 09 октября 2011

В таких случаях OOD «предпочитает» сделать класс Food абстрактным, поскольку «Ингредиенты» будут отличаться от Food для другого.Таким образом, как отмечали другие, составление этого списка static не имеет смысла, поскольку static должен быть модификатором атрибута, который не различается по объектам.

Я предлагаю решение следующим образом:1007 *

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 };
          }
  }
}
2 голосов
/ 09 октября 2011

Вы можете определить метод 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 ;
   }
}
0 голосов
/ 09 октября 2011

На самом деле вы не можете, если вы стремитесь иметь одну коллекцию ингредиентов для каждого типа. Я думаю, что лучшее, что вы могли бы сделать, хотя это не то, что я не обязательно рекомендую, это переместить ответственно в другой класс, например:

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,
        };
    }
}
0 голосов
/ 09 октября 2011

Ингредиенты не должны быть статичными. У вас могут быть разные типы тортов из класса 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
        } 
   }
} 
0 голосов
/ 09 октября 2011

Как насчет создания всех этих экземпляров одного класса? как:

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 });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...