类的实例不存在?

时间:2012-11-10 03:15:46

标签: c# instance instantiation nullreferenceexception

我正在尝试让一个单独的类中的方法为我做一些数学运算,然后将结果写入控制台。我现在遇到的问题是它说对象引用没有要使用的实例。我以为我已经在类的早期实例化了调用所有其他方法的方法,但显然有些东西是不对的,我不知道如何使其工作。数学的第二部分会给我同样的错误,但是如果我能解决这个问题,我应该能够轻松修复第二部分。

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();
    }
}

它试图引用的苹果类是:

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

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

我认为苹果apple = new Apple();会生成所需的实例,但显然不是吗?

4 个答案:

答案 0 :(得分:3)

MakeFruits方法中,您声明了两个MakeFruits()方法的本地变量,因此EatFruits()无法访问它们。

请注意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);
}

因为您在MakeFruits()方法中本地声明了水果,所以类属性applebanana保持为null

在另一种情况下,您的apple()方法未正确注册半径。它应写成如下:

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

如果您仍然不确定,请查看Mauris'crash course notes on Pastebin

答案 1 :(得分:2)

使用

Apple apple = new Apple();

您已将此版本的apple限定为MakeFruits方法。因此,在EatFruits方法中,您可以访问该范围可用的苹果版本,该版本是未初始化的Apple apple。当您尝试访问成员时,会收到错误,因为它尚未初始化。

我在这里看到的主要问题是范围和一些错过案例的使用。

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
 }
}

主程序中出现相同的问题

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();
 }
}

答案 2 :(得分:0)

你只需要知道你班级上下文之间的区别,当你使用时:

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

你告诉编译器“apple”和“banana”是局部变量,.....变量只属于“MakeFruits()”方法,你需要做的是使用关键词“this “并且编译器将知道您需要在类定义上实例化变量。

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

答案 3 :(得分:0)

首先,您需要修复Apple构造函数。

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

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

}

上面的代码说明了创建对象的正确方法。

你可能想要做这样的事情:

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 + "!";
    }

}

现在,请记住,这只是一个例子,掩盖了许多非常重要的概念。快乐的编码!