2

Uni assignment requires that we build a pizza app in C# that derives Sauce from Ingredient. I have a List<Ingredient> that is storing objects of both types.

Pizza.cs calls the method GetInstructions() which is slightly different in the derived method. Unfortunately Sauce.GetInstructions() is never being called. As you can see, there's a debug line in there that should pop up a message box when the program is executing that routine but it's not popping up. Can anyone suggest why not?

Pizza.cs contains the following method:

public string BuildInstructionList()
    {   // iterate through list of selected toppings and build a single string for display in the GUI
    int count = 1; string instructions = "";
    foreach (var i in toppings)
        {
        instructions = instructions += string.Format("Step {0}: {1}", count, i.GetInstructions());
        count++;
        }
        return instructions;
    }

Ingredient.cs contains:

public virtual string GetInstructions()
    {
        string instructionLine;
        string qty = this.GetIngredientQuantity().ToString();
        string unit = this.GetIngredientUnit();
        string name = this.GetIngredientName();
        instructionLine = string.Format("Add {0} {1} of {2} to the pizza.\n", qty, unit, name);
        return instructionLine;
    }

Sauce.cs contains:

public new string GetInstructions()
    {
        PizzaGUI.Message("I am here!");
        string instructionLine;
        string qty = this.GetIngredientQuantity().ToString();
        string unit = this.GetIngredientUnit();
        string name = this.GetIngredientName();
        instructionLine = string.Format("Apply {0} {1} of {2} to the pizza.\n", qty, unit, name);
        return instructionLine;
    }
srodden
  • 57
  • 1
  • 4

2 Answers2

2

You need to use override in place new in your Sauce.cs method.

From MSDN The override modifier extends the base class method, and the new modifier hides it.

public override string GetInstructions()
    {
        PizzaGUI.Message("I am here!");
        string instructionLine;
        string qty = this.GetIngredientQuantity().ToString();
        string unit = this.GetIngredientUnit();
        string name = this.GetIngredientName();
        instructionLine = string.Format("Apply {0} {1} of {2} to the pizza.\n", qty, unit, name);
        return instructionLine;
    }
Abhinav Galodha
  • 9,293
  • 2
  • 31
  • 41
  • Thanks. I changed that and it's now using the Sauce version, but it's using it for all toppings, not just the sauces! – srodden Jan 15 '16 at 23:36
  • Clarification, after the first time I use it, it keeps using it. E.g. if I add mushrooms then it uses the `Ingredient` version, then I add a sauce, it uses the `Sauce` version, and any subsequent toppings (onions etc.) it keeps using the `Sauce` version. – srodden Jan 15 '16 at 23:39
  • uh... actually it is and isn't. Subsequent additions of toppings are using the correct string format line (which contains the word Add) but for some reason it's triggering the messagebox! – srodden Jan 15 '16 at 23:42
  • Ignore previous comments. I was being a newb and misreading my own debug lines. They're popping up because it's iterating through and rebuilding the list each time. Thanks for the help! – srodden Jan 15 '16 at 23:50
0

In Sauce.cs,

Change:

public new string GetInstructions()

To:

public override string GetInstructions()

The new keyword will basically ignore the base definition, and create a brand new method that is also called GetInstructions, hiding the virtual method you defined in the base class. You've broken polymorphism when you do this.

I would also suggest making the Ingredient class abstract, and not define an implementation for GetInstructions.

Mike Christensen
  • 88,082
  • 50
  • 208
  • 326