1

在某些情况下,当使用其关闭按钮关闭表单时,我会得到一个 NRE,该按钮仅调用本机 (WinForms) Close() 方法。

通过代码的某些路径可以正常工作,但一个特定路径会导致空引用异常。由于名义上这是一个引用了 null 的东西的场景,所以当表单只是被关闭时怎么会发生这种情况呢?我可以想象可能存在内存泄漏,但是我不理解引用了 null 的东西。

代码中可能存在哪些潜在原因?

更新

对乔恩斯基特的回答:

由于无聊和费力的原因(再次),我无法以正常方式调试它,但我能做的是:

catch (Exception ex)
{
    MessageBox.Show(ex.Message);
    MessageBox.Show(ex.InnerException.ToString());
    SSCS.ExceptionHandler(ex, "frmEntry.saveDSD");
}

最后一种是内部/自定义异常处理方法。

我从这些行中得到的只是:

"Null Reference Exception"
Nothing (empty string)
"Exception: NullReferenceException Location: frmEntry.btnSave.click

请注意,现在显示的最后一个异常暗示 btnSave.click 是罪魁祸首,而它以前将矛头指向 saveDSD。越来越好奇。这是霍桑效应* 的一个案例吗(嗯,修改后的霍桑效应,从某种意义上说,添加此调试代码可能会改变一些事情)。

  • 典型的霍桑效应更像是这样的场景:一群猫在打篮球。一些女孩走上前来观看。猫开始炫耀和热狗,其中一只摔断了腿。是女生的错吗?不。如果他们没有观看,会发生这种情况吗?不。

更新 2

谈谈霍桑效应:当我将两个 MessageBox.Show() 调用复制到 frmEntry.btnSave.click 的 catch 块时,我得到:

"Null Reference Exception"
"Null Reference Exception"
"Exception: NullReferenceException Location: frmEntry.Closing"

IOW,当 [h,sh]e 遇到两辆相反方向的汽车时,NRE 的位置一直在移动,就像乡村道路上的松鼠一样。

更新 3

它又发生了一次:将那些 MessageBox.Show() 添加到表单的 Closing 事件中会导致 NRE 从另一个洞中弹出并声明自己。这个近交代码正在通过分数产生(或克隆)半智障,或者看起来如此。

更新 4

如果编写糟糕的代码是一种犯罪行为,那么编写这些东西的猫应该被单独监禁在 SuperMax 中。

这是最新的令人震惊的头条新闻/咆哮者:

int cancelled = ListRecords.cancelled;
if (cancelled == 0)
. . .

ListRecords 的公共“已取消”成员(在另一个类中)只分配了 0 和 1 的值。因此,取消不仅听起来像一个布尔值,它也像一个布尔值。为什么它没有被声明为布尔值?!?!?

这个代码库的官方形象应该是 Edvard Munch 的《呐喊》

更新 5

也许我是在发泄,但最近的经历使我为某些类型的代码想出了一个新名称,并为许多项目提供了一个插图。不会去任何地方,但只是占用空间的代码(进行了分配,但随后不采取行动,或调用空方法/处理程序)我现在称之为“温彻斯特神秘屋代码”。

而对于典型的项目(我现在已经是许多项目的“被俘”员工和承包商,拥有近 20 年的编程经验),我现在将这种情况比作一群人在流沙中打滚。当他们雇用新人“上船”时,他们真的希望他们与他们一起跳入流沙。这对事情有什么帮助?这只是“苦爱相伴”的案例吗?他们应该做的是说“给我们一根绳子!” 不是“进来吧,流沙没事!”

很多时候,它可能只是熵和“工作保障”在起作用;如果他们继续与他们选择或创造的怪物搏斗,那么他们来之不易的知识如何或多或少地让野兽远离,这将使他们保持半舒适的工作。如果他们做出任何根本性的改变(大多数团队都会需要做出一些根本性的改进,IMO),这可能会危及他们的就业状况。也许答案是雇用/签约“过渡团队”,将团队/公司从史前恐龙俱乐部时代转移到 21 世纪,培训“老守卫”,以便他们能够保住工作。毕竟,无论如何,这些“救世主”都不足以抢走老手的工作——训练他们,让他们加快速度,然后继续前进。所有人都会受益。但许多人似乎更愿意继续在泥潭或流沙中打滚。

在任何人雇用程序员之前,他们至少应该给他们一个测试,通过测试将证明他们至少熟悉史蒂夫麦康奈尔的“代码完成”中描述的基本原则。

好吧,回到与流沙的战斗……

更新 6

或者:“重构 Spo-dee-o-dee”:

重构的“陷阱”是如果您更改变量的名称,例如:

ChangeListType chgLst; // ChangeListType is an enum

...对此:

ChangeListType changeListType;

...如果有一个包含名为“chgLst”的列的数据表,SQL 语句也可能会被更改,如果不是你的一天,这可能会毁掉至少一部分。

另一个潜在的问题是当你得到“[var name] 仅被分配但它的值从未使用”提示时。您可能认为您可以随便 86 条所有这些,但请注意,您可能注释掉的任何相关代码以及对这些死变量的赋值都不会产生可靠的副作用。诚然,这将是一种糟糕的编码方式(副作用方法将它们的返回值存储在被忽略的 vars 中),但是......它会发生,尤其是当原始编码器是一个螺旋桨头的疯狂科学家牛仔时。

这段代码充满了反模式,如果 Butterick 和/或 Simplicity 与这个人签订合同,我不会感到惊讶。

再想一想,除了这个项目的架构、设计、编码和格式之外,它并不是真的那么糟糕......

玛丽雪莱的“科学怪人”确实很有先见之明,但不是大多数人想象的那样。它不是对技术失控的普遍预感,而是比这更具体:它是大多数现代软件项目的前瞻,从这里和那里的“部分”随意地挤在一起,几乎不考虑“髋骨与大腿骨相连”(或应该如此)以及这些部分是否匹配或会相互排斥;左手不知道右手在做什么,魔鬼在最后!等等。

4

1 回答 1

2

在以下任何一种情况下都可能发生这种情况:

  • 对象 objnull并且您的代码具有obj.ToString()
  • 字符串项null并且您的代码有item.Trim()
  • 设置 mySettingsnull,你的代码有mySettings.Path

SerialDataReceivedEventHandler不太常见的事情是运行发布信息的线程或在删除后尝试接收数据的串行端口。

查看可疑表单的代码和父表单的代码在关闭此可疑表单的时间以及可能在可疑表单上运行的其他进程的情况。

于 2013-04-09T17:16:45.753 回答