5

最近、特定の条件下で変数が初期化されず、を取得するというコーディングのバグがありましたNullReferenceException。例外が変数名を与えないので、これを再作成するためにこれを生成するデータのビットを見つけなければならなかったので、これはデバッグするのに時間がかかりました。

明らかに、使用する前にすべての変数をチェックして、有益な例外をスローすることができますが、これを行うためのより良い(より少ないコーディングを読む)方法はありますか?私が持っていたもう1つの考えはpdb、エラー情報にエラーの原因となったコード行が含まれるようにファイルを同梱することでした。他の人はこの問題をどのように回避/処理しますか?

ありがとう

4

5 に答える 5

11

まず、1つのステートメントで多くのことを行わないでください。1行に膨大な数の間接参照操作がある場合、原因を見つけるのははるかに困難になります。デメテルの法則もこれに役立ちます-あなたがそのようなものを持っているなら、あなたorder.SalesClerk.Manager.Address.Street.Lengthは例外を受け取ったときに通り抜ける多くのオプションを持っています。(私はデメテルの法則について独断的ではありませんが、すべてが適度にあります...)

次に、オブジェクトが別のタイプであることが有効asである場合を除いて、を使用するよりもキャストすることをお勧めします。これには通常、直後にnullチェックが含まれます。だからここに:

// What if foo is actually a Control, but we expect it to be String?
string text = foo as string;
// Several lines later
int length = text.Length; // Bang!

ここでは、NullReferenceExceptionが発生し、最終的にはnullにトレースバックしますが、それがnullによるものなのか、予期しないタイプによるものなtextのかはわかりません。fooそれが本当に、本当にである必要がある場合はstring、代わりにキャストします。

string text = (string) foo;

これで、2つのシナリオの違いがわかります。

第三に:他の人が言っているように、データを検証します-通常はパブリックAPIと潜在的に内部APIへの引数です。私はこれを野田時間の十分な場所で行っているので、チェックを整理するのに役立つユーティリティクラスがあります。したがって、たとえば(からPeriod):

internal LocalInstant AddTo(LocalInstant localInstant,
                            CalendarSystem calendar, int scalar)
{
    Preconditions.CheckNotNull(calendar, "calendar");
    ...
}

nullにできることとできないことも文書化する必要があります。

于 2012-04-12T16:57:51.557 に答える
3

多くの場合、アプリケーションの実行フローの任意の時点で発生する可能性のあるすべてのタイプの例外を計画して説明することはほぼ不可能です。ディフェンシブコーディングは、特定のポイントにのみ有効です。秘訣は、未処理のエラーやクラッシュに関する有意義な情報を提供できる堅実な診断スタックをアプリケーションに組み込むことです。app-domainレベルで優れたトップレベル(最後の溝)ハンドラーを持つことは、それを大いに助けます。

はい、PDBを出荷することは(リリースビルドを使用する場合でも)、正確な場所とエラーの原因を特定できる完全なスタックトレースを取得するための良い方法です。ただし、どの診断アプローチを選択する場合でも、最初にアプリケーションの設計に組み込む必要があります(理想的には)。既存のアプリを後付けすることは、面倒で時間とお金がかかる可能性があります。

于 2012-04-12T17:00:13.737 に答える
2

null参照を持たないようにコーディングするためのよりコンパクトな方法を探しているだけの場合は、null合体演算子?? MSDNを見落とさないでください。

明らかに、それはあなたがしていることに依存しますが、余分なifステートメントを避けるために使用することができます。

于 2012-04-12T17:18:22.770 に答える
2

申し訳ありませんが、特定のメソッドで使用しているオブジェクトがnullでないことを確認するために、常にチェックを行います。

それは同じくらい簡単です

if( this.SubObject == null )
{
    throw new Exception("Could not perform METHOD - SubObject is null.");
}
else
{
...
}

そうでなければ、私は徹底する方法を考えることができません。とにかくこれらのチェックを行わないことは私にはあまり意味がありません。いい習慣だと思います。

于 2012-04-12T16:58:27.390 に答える
2

まず、入力を常に検証する必要があります。許可されていない場合nullは、をスローしArgumentNullExceptionます。

今、私はそれがどのように苦痛であるかを知っているので、あなたはあなたのためにそれをするアセンブリ書き換えツールを調べることができます。アイデアは、あなたがすることができないそれらの引数をマークする一種の属性を持っているということですnull

public void Method([NotNull] string name) { ...

そして、リライターは空白を埋めるでしょう...

または、単純な拡張方法で簡単にできます

name.CheckNotNull();
于 2012-04-12T17:00:12.970 に答える