0

Newbie coder here. Working on a game of Yahtzee but can't figure out why I'm getting this error (object reference not set to instance of object) when I have corrected it already. My 'form' object is null even though I've declared an instance of it in the class constructor and a green line saying it is not being used appears.

public partial class Form1: Form {

    public Form1() {
        InitializeComponent();
    }

    private Game game;

    public void ShowMessage(string message) {
        lblMessage.Text = message;
    }

    public void StartNewGame() {
        game = new Game(this);

        }

    private void btnRoll_Click(object sender, EventArgs e) {
        game.RollDice();

    }

class Game {
    private Form1 form;

    public Game(Form1 form) {
        form = new Form1();

        }

    public void RollDice() {

        form.ShowMessage("blahblah");
    }

The "NullReferenceException" error appears over form.ShowMessage and I don't know why. I have declared a new instance of the form class in the game constructor which is run when the player selects StartNewGame which runs the StartNewGame method. The easiest way to get it working is to simply add "Form1 form" to the parameter of the RollDice() method in the Game class, and then game.RollDice(this) in the Form1 event handler. But the instruction guide for the assignment states that we shouldn't do that and we are to initialize the Form1 object in the constructor of Game. Please help I'm new and cant understand why this is happening.

Edan Fisher
  • 1
  • 1
  • 1

4 Answers4

1

Use this in constructor Game Class :

public Game(Form1 form)
{
    this.form = form;

}
Abdellah OUMGHAR
  • 3,627
  • 1
  • 11
  • 16
1

Your problem is a naming conflict in your constructor:

public Game(Form1 form)
{
    form = new Form1();
}

The parameter has the same name as the form level variable. This means the constructor code is newing up the variable you pass in and not the one at class level. You should either refer to the form variable with this qualifier, or preferably rename it.

A common practice is to use underscore prefix for class level variables:

class Game
{
    private Form1 _form;

    public Game(Form1 form) {
        _form = new Form1();

    }
}
DavidG
  • 113,891
  • 12
  • 217
  • 223
0

You are creating a new form instead of assigning the passed in form to its local variable.

class Game {
    private Form1 form;

    public Game(Form1 form) {
        *form = new Form1();*

        }

    public void RollDice() {

        form.ShowMessage("blahblah");
    }

You should change the code so the passed in form will be assigned to its local variable like this:

public Game(Form1 form) {
    this.form = form;

    }

Then it should work.

Florian Schaal
  • 2,586
  • 3
  • 39
  • 59
0

Don't let your Game class know about the Form that's calling it. That really limits the reusability of your code in the future, since now any Form that tries to use the Game class has to have a ShowMessage method to call.

Instead, just have your RollDice method return a string...

class Game
{
    public void RollDice()
    {
        // do important 'roll dice' stuff...

        return "blahblah";
    }
}

And then have your Form handle the return value appropriately.

private void btnRoll_Click(object sender, EventArgs e)
{
    string message = game.RollDice();

    lblMessage.Text = message;
}

That completely gets around the need to pass the Form into your Game class, and avoids a lot of opportunities for getting a NullReferenceException.

Grant Winney
  • 65,241
  • 13
  • 115
  • 165