3

I'm trying to have a method in a separate class do some math for me, and then write the result into the console. The issue I'm hitting now is that its saying the object reference doesn't have an instance to use. I thought I had instantiated it earlier in the class that the method that calls all the other methods is in, but apparently something isn't right, and I have no clue what to do to make it work. The second section of math will give me the same error, but if i can fix this one I should be able to fix the second one easily.

class FruitGarden
{
    private Apple apple;
    private Banana banana;
    static void Main(string[] args)
    {
        FruitGarden fruitGarden = new FruitGarden();
        fruitGarden.EatFruits();
    }
    public void MakeFruits()
    {
        Apple apple = new Apple();
        apple.apple(1.5);
        Banana banana = new Banana();
        banana.banana(3.5);
    }
    public void EatFruits()
    {
        double dblpercent;
        MakeFruits();
        Console.WriteLine("You have an Apple and a Banana in your fruit garden.\n");
        Console.WriteLine("What Percent of the Apple would you like to eat?");
        dblpercent = Convert.ToDouble(Console.ReadLine());
        Console.WriteLine("\nWhat Percent of the Banana would you like to eat?");
        dblpercent = Convert.ToDouble(Console.ReadLine());
        Console.Write("You have ");
        apple.Eat(dblpercent);
        Console.Write("% of your apple, and ");
        banana.Eat(dblpercent);
        Console.Write("% of your banana left.");
        Console.ReadLine();
    }
}

The apple class that its trying to reference is:

class Apple : Fruit
{
    public double Radius { get;set;}

    public void apple(double radius)
    {
        Radius = Radius;
    }
}

I thought the apple apple = new Apple(); would make the instance it needed, but apparently not?

user1787114
  • 207
  • 2
  • 5
  • 15

4 Answers4

3

In the MakeFruits method, you declared two variables which are local to your MakeFruits() method and hence EatFruits() have no access to them.

Note the this.:

public void MakeFruits()
{
    this.apple = new Apple(); // "this." is written to make it clearer. 
    this.apple.apple(1.5);    // let's not skip the steps
    this.banana = new Banana();
    this.banana.banana(3.5);
}

Because you declared the fruits locally in the MakeFruits() method, the class properties apple and banana stays as null.

In another case, your apple() method did not register radius properly. It should be written as follows:

public void SetRadius (double radius)
{
    Radius = radius; // by Alexei
}

In any case if you're still unsure, take a look at Mauris' crash course notes on Pastebin.

mauris
  • 42,982
  • 15
  • 99
  • 131
Andy
  • 8,432
  • 6
  • 38
  • 76
  • i made the changes, but now it is telling me "'Apple": member names cannot be the same as their enclosing type" in the apple class.... >_> i feel like a total noob – user1787114 Nov 10 '12 at 03:32
  • @alexeilevenkov thanks forth edits – Andy Nov 10 '12 at 03:34
  • 1
    You can't have a method which is thecsame name as the class – Andy Nov 10 '12 at 03:37
  • 1
    @mauris, You are absolutely right - there is no SO in `Radius=Radius`... (and I know what I was thinking - `Radius {get;set{Raduis=value;}}` - why... I guess need more coffee... – Alexei Levenkov Nov 10 '12 at 03:49
  • @user1787114 take a look at the pastebin notes. – mauris Nov 10 '12 at 03:49
  • Here, have your coffee. *passes :coffee:* I just had mine. – mauris Nov 10 '12 at 03:49
  • fixed it. now i just need to figure out how to get the output of the eat method to write. apparently " public double Eat(double dblpercent) { return (PercentFruitLeft-dblpercent); } " doesnt actually write the value in the command prompt – user1787114 Nov 10 '12 at 03:50
  • +1 comment from mauris : for original sample code constructors (which your "apple" method looks like) need to match class name. (I've deleted original wrong comment about SO, re-adding remark about constructor-like method) – Alexei Levenkov Nov 10 '12 at 03:51
  • it wont debug..... ill hit the play button in visual studio and nothing will happen.... i think i broke it haha – user1787114 Nov 10 '12 at 04:27
  • @user1787114 It probably won't debug because its not compiling anymore. Check the Errors window to see what you need to do to fix it. It seems you're probably new to this stuff, I recommend getting a C# beginners book which will cover the basics like this. – Andy Nov 10 '12 at 14:50
2

By using

Apple apple = new Apple();

you have scoped this version of apple to the MakeFruits method. Thus, when in your EatFruits method, you access the version of apple available to that scope, which is an uninitialized Apple apple. When you try to access members, you get an error because it has not been initialized.

The main issue I see here is scope and some miss use of case.

class Apple : Fruit
{
 public double Radius { get;set;}

 //public void apple(double radius)//Constructors need to share the same case 
                                 //as their parent and inherently have no return value
 public Apple(double radius)
 {
    //Radius = Radius;//This is a self reference
    Radius = radius;//This will reference the local variable to Apple, Radius
 }
}

The same issues appear in the main program

class FruitGarden
{
 private Apple apple;
 private Banana banana;
 static void Main(string[] args)
 {
    FruitGarden fruitGarden = new FruitGarden();
    fruitGarden.EatFruits();
 }
 public void MakeFruits()
 {
    //Apple apple = new Apple();//You have already declared apple in this scope
    //apple.apple(1.5);//This is redundant, what you most likely want is to have this done in a constructor
    apple = new Apple(1.5);//this accesses the scoped apple, and uses the Apple constructor
    //Banana banana = new Banana();//same scopeing issue as apple
    banana = new Banana();
    banana.banana(3.5);//the banana class was not shown so I will leave this
 }
 public void EatFruits()
 {
    double dblpercent;
    MakeFruits();//now made properly with scope
    Console.WriteLine("You have an Apple and a Banana in your fruit garden.\n");
    Console.WriteLine("What Percent of the Apple would you like to eat?");
    dblpercent = Convert.ToDouble(Console.ReadLine());
    Console.WriteLine("\nWhat Percent of the Banana would you like to eat?");
    dblpercent = Convert.ToDouble(Console.ReadLine());
    Console.Write("You have ");
    apple.Eat(dblpercent);//Eat was never shown
    Console.Write("% of your apple, and ");
    banana.Eat(dblpercent);//Eat was never shown
    Console.Write("% of your banana left.");
    Console.ReadLine();
 }
}
Travis J
  • 81,153
  • 41
  • 202
  • 273
0

you only need to know the difference between contexts on your class, when you use:

public void MakeFruits()
{
    Apple apple = new Apple();
    apple.apple(1.5);
    Banana banana = new Banana();
    banana.banana(3.5);
}

you are telling the compiler that "apple" and "banana" are local variables, ..... variables that belong only to the method "MakeFruits()", what you need to do is use the key word "this" and the compiler will know that you need to instantiate the variables on your class definition.

public void MakeFruits()
{
    this.apple = new Apple();
    apple.apple(1.5);
    this.banana = new Banana();
    banana.banana(3.5);
}
Montana
  • 67
  • 1
  • 5
0

To begin with, you'll need to fix the Apple constructor.

class Apple : Fruit
{
    public double Radius { get;set;}

    public Apple(double radius)
    {
        Radius = radius;
    }

}

The code above illustrates the correct way to create your object.

You may want to look into doing something like this:

class Program
{

    private static FruitGarden myGarden;

    static void Main(string[] args)
    {
        //get a new garden

        myGarden = new FruitGarden();
        Console.WriteLine(myGarden.PlantFruit("banana")); 
        //returns "You grew one banana!"
        Console.WriteLine(myGarden.PlantFruit("apple")); 
        //returns "You grew one apple!"
        Console.WriteLine(myGarden.PlantFruit("orange")); 
        //returns "You can't grow that type of fruit!"

        EatFruits();
    }

    static void EatFruits()
    {
        //Now, let's just iterate through our fruit garden and eat all of that 
        //yummy fruit!
        for (int i = 0; i < myGarden.Fruits.Count; i++)
        {
            Fruit myFruitSnack = myGarden.Fruits[i];
            while (myFruitSnack.FruitSize > 0)
            {
                Console.WriteLine(myFruitSnack.TakeBite());
            }
        }

        Console.ReadLine();
    }

}

//We could make this virtual or an interface, but I'll leave that out for now.
public class Fruit
{

    private int fruitSize;

    public int FruitSize
    {
        get
        {
            return this.fruitSize;
        }
    }

    public Fruit(int size)
    {
        this.fruitSize = size;
    }

    //The size of the fruit is an internal property. You can see how 
    //big it is, of course, but you can't magically make a fruit smaller
    //or larger unless you interact with it in a way that is allowable
    //according to the current known laws of the universe and agriculture. 
    //I.E, you can take a bite :)
    public string TakeBite()
    {
        if (this.fruitSize > 0)
        {
            this.fruitSize -= 1; //or any other value you decide to use
        }

        if (this.fruitSize > 0)
        {
            //again, there is so much more you can do here.
            return "You take a bite of the fruit!"; 
        }
        else
        {
            return "You take one more big bite and eat all of the fruit!";
        }

    }

}

public class Apple : Fruit
{
    //Someday, you might want to overload these...
    public Apple(int fruitSize)
        : base(fruitSize)
    {

    }
}

public class Banana : Fruit
{
    //Someday, you might want to overload these...
    public Banana(int fruitSize)
        : base(fruitSize)
    {

    }
}

class FruitGarden
{

    //Public property of FruitGarden that contains all of the fruits it has "grown."
    public List<Fruit> Fruits { get; set; }

    public FruitGarden()
    {
        //Instantiate your list now.
        this.Fruits = new List<Fruit>();
    }

    //There are better ways to do this, but for the sake of your project we're
    //going to do something simple. We'll pass in a string representing the 
    //fruit type.
    public string PlantFruit(string fruitType)
    {
        //We're going to implement a simple factory here. Google 'factory pattern'
        //later and be prepared to spend a lot of time reading over the ideas
        //you're going to run into.
        switch (fruitType.ToLower())
        {
            case "apple":
                this.Fruits.Add(new Apple(10));
                break;
            case "banana":
                this.Fruits.Add(new Banana(5));
                break;
            default:
                return "You can't grow that type of fruit!";
        }

        return "You grew one " + fruitType + "!";
    }

}

Now, keep in mind this is just an example and glosses over a lot of really important concepts. Happy coding!

elucid8
  • 1,412
  • 4
  • 19
  • 40