对象引用未设置为对象的实例?但事实果真如此?C# [重复]

Object reference not set to an instance of an object? But it is? C# [duplicate]

提问人:Edan Fisher 提问时间:6/4/2016 更新时间:6/4/2016 访问量:4328

问:

新手编码员在这里。正在开发 Yahtzee 游戏,但无法弄清楚为什么我已经更正了它时会出现此错误(对象引用未设置为对象实例)。我的“form”对象是 null,即使我已经在类构造函数中声明了它的实例,并且出现了一条绿线,表示它没有被使用。

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

“NullReferenceException”错误出现在窗体上。ShowMessage,我不知道为什么。我在游戏构造函数中声明了表单类的新实例,当玩家选择运行 StartNewGame 方法的 StartNewGame 时,该实例将运行。让它工作的最简单方法是简单地将“Form1 form”添加到 Game 类中 RollDice() 方法的参数中,然后添加 game。RollDice(this) 在 Form1 事件处理程序中。但是赋值的说明指南指出我们不应该这样做,我们要在 Game 的构造函数中初始化 Form1 对象。请帮助我是新手,不明白为什么会发生这种情况。

C# 对象 NullReferenceException

评论

1赞 Nikola 6/4/2016
在何时何地调用该方法?StartNewGame

答:

1赞 Abdellah OUMGHAR 6/4/2016 #1

在构造函数中使用它:Game Class

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

}

评论

0赞 Edan Fisher 6/4/2016
谢谢,它有效!谢谢你的教育,我的学校老师不能给我哈哈!
0赞 DavidG 6/4/2016
@AbdellahOUMGHAR不要乞求接受,这是不好的做法
1赞 DavidG 6/4/2016 #2

您的问题是构造函数中的命名冲突:

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

该参数与窗体级别变量同名。这意味着构造函数代码正在启动您传入的变量,而不是类级别的变量。您应该使用限定符引用表单变量,或者最好重命名它。newthis

一种常见的做法是为类级变量使用下划线前缀:

class Game
{
    private Form1 _form;

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

    }
}
0赞 Florian Schaal 6/4/2016 #3

您正在创建一个新表单,而不是将传入的表单分配给其局部变量。

class Game {
    private Form1 form;

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

        }

    public void RollDice() {

        form.ShowMessage("blahblah");
    }

您应该更改代码,以便将传入的表单分配给其局部变量,如下所示:

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

    }

然后它应该起作用。

0赞 Grant Winney 6/4/2016 #4

不要让你的班级知道那个叫它的人。这确实限制了将来代码的可重用性,因为现在任何尝试使用该类的人都必须有一个要调用的方法。GameFormFormGameShowMessage

相反,只需让您的方法返回一个字符串......RollDice

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

        return "blahblah";
    }
}

然后适当地处理返回值。Form

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

    lblMessage.Text = message;
}

这完全避免了将 传递给您的班级的需要,并避免了很多获得 .FormGameNullReferenceException