特定の状況下で、ネイティブ (WinForms) の Close() メソッドを呼び出すだけの [閉じる] ボタンを使用してフォームを閉じると、NRE が発生します。
コード内の特定のパスは問題ありませんが、特定のパスの 1 つが Null 参照例外を引き起こします。これは名目上、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
表示されている最後の例外は、以前は saveDSD に指を向けていましたが、btnSave.click が原因であることを示していることに注意してください。好奇心旺盛で好奇心旺盛。これは、ホーソン効果* が実際に働いているケースですか (このデバッグ コードを追加すると状況が変わる可能性があるという意味で、修正されたホーソン効果です)。
- 標準的なホーソン効果は、この種のシナリオに似ています。猫の群れがバスケットボールをしています。何人かの女の子が歩いて見ています。猫は見せびらかしてホットドッグを始め、1匹は足を骨折します。女の子のせい?いいえ。彼らが見ていなかったら、それは起こっていたでしょうか? いいえ。
更新 2
Hawthorne 効果について話します。2 つの MessageBox.Show() 呼び出しを frmEntry.btnSave.click の catch ブロックにコピーすると、次のようになりました。
"Null Reference Exception"
"Null Reference Exception"
"Exception: NullReferenceException Location: frmEntry.Closing"
ああ、NRE の場所は、[h,she]e が反対方向に進む 2 台の車に出くわしたときの田舎道でのリスのように動き続けます。
更新 3
これらの MessageBox.Show() をフォームの Closing イベントに追加すると、NRE が別の穴から飛び出し、それ自体を宣言します。この同系交配のコードは、スコアによって中途半端な知恵を生んでいる (または複製している) か、そう思われます。
更新 4
悪いコードを書くことが犯罪であるなら、このようなことを書いた猫は SuperMax で独房に監禁されるべきです。
最新のひどいヘッドスクラッチャー/ハウラーは次のとおりです。
int cancelled = ListRecords.cancelled;
if (cancelled == 0)
. . .
ListRecords (別のクラス) の public "cancelled" メンバーには、0 と 1 の値のみが割り当てられます。したがって、cancelledは bool のように聞こえるだけでなく、bool のようにも機能します。なぜブール値として宣言されなかったのですか?!?!?
このコードベースの公式イメージは、エドヴァルド・ムンクの「叫び」です。
更新 5
多分私は気を紛らわせているのかもしれませんが、最近の経験から、特定の種類のコードに新しい名前を付けたり、多くのプロジェクトにイラストを付けたりするようになりました。どこにも行かず、スペースを占有するだけのコード (代入は行われるが実行されない、または空のメソッド/ハンドラーが呼び出される) を、私は現在、「ウィンチェスター ミステリー ハウス コード」と呼んでいます。
そして、典型的なプロジェクト (私は「捕らえられた」従業員であり、多くのプロジェクトの請負業者であり、プログラミングの経験は 20 年近くあります) について、この状況を流砂でうろついている人々のグループに例えます。彼らが新しい人を雇って「乗船」させるとき、彼らは彼らが一緒に流砂に飛び込むことを本当に望んでいます. これはどのように問題を解決するのに役立ちますか? それは単に「ミザリー ラブズ カンパニー」のケースですか?彼らがすべきことは、「私たちにロープを投げてください!」と言うことです。「さあ、流砂は大丈夫だ!」ではありません。
多くの場合、それはおそらくエントロピーと「雇用の安定」が原因です。彼らが選択または作成した怪物と格闘し続ける場合、獣を多かれ少なかれ寄せ付けないようにする方法についての彼らの苦労して獲得した知識は、彼らを半快適な仕事に保ちます. 彼らが抜本的な変更を行った場合 (ほとんどのチームはいくつかの抜本的な改善を行う必要がある、IMO)、これは彼らの雇用状況を危険にさらす可能性があります。おそらく答えは、「移行チーム」を雇用/契約して、チーム/会社を先史時代の恐竜クラブの時代から21世紀に移行させ、「古い警備員」を訓練して彼らの仕事を維持できるようにすることです. 結局のところ、これらの「救世主」は、いずれにせよベテランの仕事を盗むには十分ではありません。すべてが恩恵を受けるでしょう。しかし、多くの人は、泥沼や流砂でうろつき続けることを好むようです。
プログラマーを雇う前に、少なくとも、Steve McConnell の「コード コンプリート」で説明されている基本的な原則に少なくとも精通していることを証明するテストを行う必要があります。
さて、流砂との戦いに戻ります...
更新 6
または: 「Spo-dee-o-dee のリファクタリング」:
リファクタリングの「落とし穴」は、次のように変数の名前を変更した場合です。
ChangeListType chgLst; // ChangeListType is an enum
...これに:
ChangeListType changeListType;
...そして、「chgLst」という名前の列を持つデータ テーブルがある場合、SQL ステートメントも変更される可能性があり、1 日ではないにしても、少なくともその一部が台無しになる可能性があります。
もう 1 つの潜在的な落とし穴は、「[var name] は割り当てられているだけですが、その値は決して使用されていません」というヒントを得た場合です。これらすべてを無頓着に86できると思うかもしれませんが、これらの死んだ変数への割り当てとともにコメントアウトする可能性のある関連コードは、信頼できる副作用を生成していないことに注意してください. 確かに、これはコーディングするのに悪い方法です (無視される var に戻り値を格納する副次的なメソッド) が、特に元のコーダーがプロペラ頭のマッドサイエンティスト カウボーイであった場合に起こります。
このコードにはアンチパターンがぎっしり詰まっているので、Butterick や Simplicity がこの男に契約を結んだとしても驚かないでしょう。
よく考えてみると、このプロジェクトのアーキテクチャ、デザイン、コーディング、およびフォーマットを除けば、それほど悪いものではありません...
メアリー・シェリーの「フランケンシュタイン」は確かに非常に先見の明がありましたが、ほとんどの人が考えていた方法ではありませんでした. 技術の暴走についての一般的な予言ではなく、それよりもはるかに具体的なものです。それは、ほとんどの最新のソフトウェア プロジェクトの前兆です。股関節の骨が太ももの骨に接続されている」(または接続されている必要がある)、およびそれらの部分が一致するか、または互いに拒否するかどうか。左手は右手が何をしているのかわからず、悪魔は最後尾を取る! 等。