访问某个对象时的 NullReferenceException

本文关键字:NullReferenceException 对象 访问 | 更新日期: 2023-09-27 17:59:29

我知道这是一个菜鸟错误,但我真的无法发现为什么当我访问已设置的对象时会出现它。

xlocyloc都是局部变量。

gameBorder.FormInstance.tableLayoutPanel1.GetControlFromPosition(xloc, yloc).BackgroundImage = Properties.Resources.Image;

但是,这已在窗体类中设置:

namespace csharp_build
{
    public partial class gameBorder : Form
    {
        public static gameBorder FormInstance;
        public gameBorder()
        {
            FormInstance = this; 
            InitializeComponent();            
        }
    }
}

知道为什么会这样吗?这是否与以下事实有关:表单类被引用为 gameBorder ,这就是构造函数的名称,并且解决方案资源管理器中表单类的名称是 Form1.cs?
我知道这是一个菜鸟问题,我确实道歉,但任何帮助将不胜感激。

访问某个对象时的 NullReferenceException

如果您确定tableLayoutPanel1存在且不为 null,请将您的代码更改为 this,看看会发生什么:

  var control = gameBorder.FormInstance.tableLayoutPanel1.GetControlFromPosition
      (xloc, yloc);
  if (control == null) throw new NullReferenceException(
           "No control at those coordinates");
  control.BackgroundImage = Properties.Resources.Image;

哎呀,伙计们,这是用于分析、调试的代码,以帮助找出问题的原因,仅此而已......

警告:不用作最终生产代码
感谢下面的@SriramSakthivel评论,请注意,此处抛出NullReferenceException仅用于调试/分析目的,并且永远不应由生产版本中的应用程序代码抛出。

链接成员和方法结果的方式使得很难一目了然地确定导致引发NullReferenceException的原因。 如果在创建任何gameBorder实例之前访问FormInstance,则可以null。虽然不太可能,但tableLayoutPanel也可能null。如果指定的单元格上没有控件,则GetControlFromPosition方法的结果也可能是。

当你在这种代码中遇到这种问题时,最好的办法是分解调用链。这样,您将能够快速判断问题所在。

您还可以进行代码断言,如下所示:

var formInstance = gameBorder.FormInstance;
Debug.Assert(formInstance != null);
var controlAtPos = formInstance.tableLayoutPanel1.GetControlFromPosition(xloc, yloc);
Debug.Assert(controlAtPos != null);
controlAtPos.BackgroundImage = Properties.Resources.Image; // You may want to make some assertions on resolving your image instance too
代码

断言的美妙之处在于,很容易将这些断言排除在编译到生产代码之外。默认情况下,它在调试配置中编译,并在发布配置中排除。这样,您就可以从它提供的调试帮助中受益,而无需担心已部署代码中的额外开销。

请记住这一点,如果您将来再次遇到此问题,这将很有用。