web-dev-qa-db-ja.com

C#でのコンストラクターの結果の確認

これと同様の方法でnullのコンストラクターの結果をチェックする癖がある同僚とコードベースの作業をしています

Person p = new Person();
if (p != null)
{
    p.Name = "John Smith";
}

.NETランドスケープについての私の理解は、例外がスローされない限り、コンストラクターが割り当てを満たされないままにすることは決してないということです。したがって、上記のケースでは、nullチェックは役に立ちません。 pが割り当てられているか、例外がスローされてプロパティセッターがスキップされます。

ついでにこれについて同僚に尋ねたところ、「念のため」という言葉に沿って受動的な答えを得ました。私はこの種の「パロニアプログラミング」が好きではありません。読みやすさが損なわれ、不必要に循環的複雑度が増すと思います。このため、この慣行の中止を正式に要請したいと思います。これは合理的な要求ですか?何か不足していますか?

8
Jason Tyler

私はあなたの戦いを選ぶことについて@MartinMaatに同意します。

これらの多くのルールが言語で修正されているにもかかわらず、実際には言語が理解されていないために「念のため」の多くのケースがあります-の優先ルールが理解されていないために必要としない式を括弧でくくって言語。しかし、それでも、そのような習慣はほとんど無害です。

私は若い頃、言語の詳細を学び、そのような余分なコードを書かないようにすべきだと感じました。 (私の不満の1つは、不要な括弧を付けたreturn (0);でした。)しかし、特にクライアントからサーバーにジャンプするなど、非常に多くの異なる言語を使用しているため、特にその位置を調整します。 。それで、私は今いくつかのそのような問題のためにいくつかのたるみを切りました。

あなたは、サイクロマティックが論理的に推論された議論に取り掛かり始めることについてポイントです。 コードカバレッジ を見てみましょう。特に カバレッジのレベルが高い

  1. それぞれの決定はすべての可能な結果を​​取ります

新しい操作でNULLを強制的に返すことはできないため、この条件付き操作で、より高いレベルのコードカバレッジに到達する方法はありません。もちろん、これは組織にとって重要な場合とそうでない場合があります。

ただし、このコードカバレッジの問題のため、括弧の過剰よりも優先します。

一方、コード生成、JIT、およびオプティマイザはすべて、newedの値がnullになることはないことを理解しているため、基になる生成コードはおそらくこのために1ビットも影響を受けません。したがって、実際のコストは、可読性とソースコードカバレッジ機能の点でのみ発生します。

そのようなifステートメントの「else-part」はどのように見えるのですか?

他の部分がない場合、私は単にルーチンの終わりから落ちるか、または他のコードに落ちる(すなわち、このelseがないif)は潜在的に危険であると主張します。この「念のため」は、論理的には、呼び出し元やその次のコードがNULLも処理することを示唆しています。

それが読んだ場合:

p = new Object ();
if ( p != null ) {
    p.field = value;
}
else {
    throw new NullReferenceException ();
}

言語が私たちのためにそれをすべて行うので、これは本当にやり過ぎです。

条件の意味を逆にすることをお勧めします—おそらくあなたの同僚はこれでより快適になるでしょう:

p = new Object ();
if ( p == null ) {
    throw new NullReferenceException ();
}
else {
    p.field = value;
}

これで、elseラッパーの削除を主張できます。これは非常に明らかに不要であるためです。

p = new Object ();
if ( p == null ) {
    throw new NullReferenceException ();
}
p.field = value;

これにより、「念のため」が条件付きになりましたが、後続のコードは条件付きではありません。このアプローチは、割り当てが失敗したときに適切な応答がスローされることをさらに強化します。この方法やこの呼び出しチェーンでコードを実行し続けることはありません(割り当ての失敗の他の適切な処理なしで)。

したがって、要約すると、この慣行に対してここで論理的に推論される2つの議論があります。

  1. メモリー不足(またはコンストラクターの失敗)がnullを返すことを強制できないため、より高いコードカバレッジレベルに到達できません。
  2. (上記の質問に示されているように)「念のため」は不完全であり、欠陥があるp.field = value;を超えた、または貼り付けた他のコードでnullを処理する方法についての予想の不一致が原因です。

基本的に、おそらくあなたの同僚は例外の使用について垣間見えているようです—そのようなことをここではC#で行うことはできませんが。 (十分にテストされたコードが必要な場合nullを処理するための例外モデルと、nullの戻り値を並べて使用する非例外モデルの両方をコーディングすることはできません。 )おそらく、これらのトピックを通して同僚と推論すると、彼らは少し光を見るでしょう!

12
Erik Eidt

おそらく、問題を回避して、より簡単な新しいc#構文があることを彼に知らせることができます(そして、nullチェックを実行します!)

の代わりに

Person p = new Person();
if (p != null)
{
    p.Name = "John Smith";
}

書く

var p = new Person
{
    Name = "John Smith"
};
8
John Wu

それは合理的な要求ですが、これはすでにあなたと彼の間の闘争になっているようです。あなたはすでに彼にそれを指摘しているかもしれません、彼はそれを変更するのをためらっていて、今あなたは問題をエスカレートすることを計画しています。その後、「勝つ」ことができます。

Robert Harveyが投稿したリンクを彼に送信し、「興味深いと思われるC#オブジェクトの構築に関するリンクを送信しました」と言ってそのままにしておく方がスムーズな場合があります。それは彼が何をしているのか正確には有害ではなく(ただ無意味です)、後でopをきれいにするのは簡単です。私は言っている:あなたの戦いを選択してください。私は何度もこの状況に直面しており、振り返ってみると、多くの場合、苦労するだけの価値はありませんでした。事実上何もせずに簡単にお互いを憎むようになります。はい、あなたは正しいですが、それはあなたと彼だけですが、あなたはいくつかの共通の基盤を維持したいかもしれません。

4
Martin Maat

あなたの技術的な質問はすでに回答されている(nullチェックは無意味です)ので、私はあなたの質問の別の側面に焦点を当てたいと思います-そのような状況に一般的に対処する方法:いくつかの基本的な事実を知らない同僚すべてのユーザーが使用するツールについて、したがって、ツールを最適ではない方法で使用します。

場合によっては、それほど影響がないこともあります。彼らが彼らの仕事を成し遂げ、あなたの仕事に干渉しないなら、あなたは問題を無視することができます。

他の場合(例:あなたの場合)、それらはdoが少なくともある程度はあなたの仕事を妨害します。それについて何をしますか?

多くの詳細に依存すると思います。たとえば、あなたとあなたの同僚が会社にいてどれくらいの期間、会社は一般的にそのような問題にどのように対処しますか、問題はどのくらい影響しますか/あなたをいらいらさせますか、あなたは同僚とどのくらいうまくやっていくことができますか?同僚とあなたとの関係、問題を引き起こしたりエスカレートしたりすることがこの関係にどの程度影響するかなど.

私の個人的な見解は次のとおりです。エンジニアはツールを知っておくべきであり、ソフトウェアエンジニアはプログラミング言語を知っているべきだと思います。もちろん、誰もすべての詳細を知っているわけではありませんが、コンストラクタがnullを返さないことは非常に基本的な考え方です-誰もがそれを知っている必要があります。このような無意味なnullチェックを含むコードを処理する必要がある場合は、単にそれらを削除します。同僚がなぜそれらを削除したのかと尋ねられたら、なぜ彼らが無意味なのかを説明します。 (必要に応じて、完全に不要なコードを削除する必要がある理由も説明します。)長い目で見れば、これはこれらの無意味なnullチェックがないコードにつながるでしょう。

これはやや傲慢に聞こえるかもしれません、そしてそれは誰にとっても正しいアプローチではないかもしれません。私は忍耐強く、物事を説明するのが得意だと言われてきました。たぶんそれが私がこのアプローチをすぐに回避する傾向がある理由です。 :-)

あなたは「この慣行をやめるという正式な要求」に言及しています。私はそのような詳細な正式なルールを持つ会社で働いたことはありませんが、とにかくいくつかの考えがあります。繰り返しますが、あなたの最善の行動は詳細に依存すると思います。そのようなリクエストを提出すると、同僚やマネージャーの目には同僚の見栄えが悪くなる場合は、おそらくそれを行いません。一方、そのようなリクエストが一般的に歓迎される改善と見なされ、他の人がこのルールを以前に守っていなかったために同僚を非難しない場合は、先に進んでください。誰も害を受けることはなく、誰もが元気になるでしょう。


しかし、問題に対処する良い方法が見つからなかった場合は、皮肉に頼り、次のようなコードをどこにでも追加することができます。

int c = a + b;
if (c == a + b)
{
    // next steps
}
else 
{
    throw new ArithmeticException();
}

コンストラクタ呼び出し後のnullチェックと同じくらい無意味ですが、さらに明白です。そしてもちろん、私は実際にはこれをしません。同僚にうんざりして、とにかく辞めるつもりでない限り。 ;-)