2016-06-04 7 views
0

Neuling Coder hier. Ich arbeite an einem Spiel von Yahtzee, kann aber nicht herausfinden, warum ich diesen Fehler bekomme (Objektreferenz nicht auf Instanz des Objekts gesetzt), wenn ich es bereits korrigiert habe. Mein 'Formular'-Objekt ist NULL, obwohl ich im Klassenkonstruktor eine Instanz davon deklariert habe und eine grüne Zeile, die besagt, dass es nicht verwendet wird, erscheint.Objektverweis nicht auf eine Instanz eines Objekts gesetzt? Aber es ist? C#

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

Der Fehler "NullReferenceException" erscheint über form.ShowMessage und ich weiß nicht warum. Ich habe im Spielkonstruktor eine neue Instanz der Formklasse deklariert, die ausgeführt wird, wenn der Spieler StartNewGame auswählt, das die StartNewGame-Methode ausführt. Der einfachste Weg, um es zum Laufen zu bringen, ist einfach "Form1 form" zum Parameter der RollDice() -Methode in der Game-Klasse hinzuzufügen und dann game.RollDice (this) im Form1-Event-Handler. Aber die Anleitung für die Zuweisung besagt, dass wir das nicht tun sollten und wir das Form1-Objekt im Konstruktor von Game initialisieren sollen. Bitte helfen Sie mir, ich bin neu und kann nicht verstehen, warum das passiert.

+1

Wo/Wann rufen Sie die 'StartNewGame' Methode auf? – Nikola

Antwort

1

verwendet in Konstruktor Game Class:

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

} 
+0

Danke, es funktioniert!Danke für die Ausbildung, die mein Schullehrer mir nicht geben konnte, haha! –

+0

@AbdellahOUMGHAR betteln nicht um akzeptiert, es ist eine schlechte Übung – DavidG

1

Ihr Problem ist ein Namenskonflikt in Ihrem Konstruktor:

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

Der Parameter hat die gleichen Namen wie die Formularebene variabel. Dies bedeutet, dass der Konstruktorcode new die übergebene Variable und nicht die Klasse auf Klassenebene enthält. Sie sollten entweder auf die Formularvariable mit this Qualifier verweisen oder sie vorzugsweise umbenennen.

Eine gängige Praxis ist Strich Präfix für Klassenstufe Variablen zu verwenden:

class Game 
{ 
    private Form1 _form; 

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

    } 
} 
0

Sie sind eine neue Form zu schaffen, anstatt die übergebene in Form ihrer lokalen Variablen zugewiesen wird.

class Game { 
    private Form1 form; 

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

     } 

    public void RollDice() { 

     form.ShowMessage("blahblah"); 
    } 

Sie sollten den Code ändern, so dass die in Form weitergegeben wird auf seiner lokalen Variablen wie folgt zugewiesen werden:

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

    } 

Dann sollte es funktionieren.

0

Lassen Sie nicht Ihre Game Klasse über die Form wissen, die es anruft. Das begrenzt die Wiederverwendbarkeit Ihres Codes in der Zukunft wirklich, seit jetzt anyForm versucht, die Game Klasse zu verwenden, muss eine ShowMessage Methode haben, um aufzurufen.

Stattdessen müssen nur Ihre RollDice Methode einen String zurückgeben ...

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

     return "blahblah"; 
    } 
} 

Und dann haben Form Griff entsprechend den Rückgabewert.

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

    lblMessage.Text = message; 
} 

Das vollständig um die Notwendigkeit, bekommt die Form in Ihre Game Klasse übergeben, und vermeidet eine Menge Möglichkeiten für einen NullReferenceException bekommen.

Verwandte Themen