質問

次のようなものを数回見ましたが…嫌いです。これは基本的に言語を「だます」のですか?または.IsNullOrEmptyが常に最初に評価されるため、これを「OK」と見なしますか?

(文字列が関数から出てきたときにNULLであるかどうかを議論することもできますが、それは実際には問題ではありません。)

string someString;
someString = MagicFunction();

if (!string.IsNullOrEmpty(someString) && someString.Length > 3)
{
    // normal string, do whatever
}
else
{
   // On a NULL string, it drops to here, because first evaluation of IsNullOrEmpty fails
   // However, the Length function, if used by itself, would throw an exception.
}

編集: この言語の基本を思い出させてくれたすべての人に感謝します。 「なぜ」を知っていた間それはうまくいきました。コンセプトの名前を知らなかったか、覚えていなかったとは信じられません。

(バックグラウンドが必要な場合..コードのさまざまな場所でNULL文字列および.Length> x例外によって生成された例外のトラブルシューティング中にこの問題に遭遇しました。したがって、上記のコードを見たとき、他のすべてに、そこから私の欲求不満が引き継がれました。)

役に立ちましたか?

解決

あなたは、短絡と呼ばれる言語機能を利用しています。これは言語をごまかすことではありませんが、実際には、使用するように設計された機能を正確に使用しています。

他のヒント

「短絡」に依存してもよいかどうかを尋ねる場合関係演算子&& および || 、それからはい、まったく問題ありません。

これには何も問題はありません。nullpointer例外が発生しないことを確認したいだけです。

それは合理的だと思います。

拡張機能を使用すると、よりクリーンにすることができますが、基本的な概念は依然として有効です。

このコードは完全に有効ですが、null型チェックを避けるためにNull Coalesce演算子を使用したいです。

string someString = MagicFunction() ?? string.Empty;
if (someString.Length > 3)
{
    // normal string, do whatever
}
else
{
   // NULL strings will be converted to Length = 0 and will end up here.
}

これに問題はありません。

if(条件は左から右に評価されるため、このようにスタックしても問題ありません。

これは私の意見では有効なコードです(変数を宣言して次の行に代入するのはかなり面倒ですが)、おそらくelse-blockは、文字列は< 3。

それは、論理的短絡の完全に合理的な使用のように見えます。もしあるとすれば、それは言語で 不正をしています。私は最近、VB6から来ましたが、VB6はこれまで短絡していませんでした。

注意すべき問題の1つは、そのelse節でNullを再度テストする必要がある場合があることです。 。

これは完全に有効であり、そのように使用しても何も問題はありません。文書化された言語の動作に従っている場合、すべてが順調です。 C#では、使用している構文は条件付き論理演算子であり、ドキュメンテーションされたbahviourは MSDN

私にとっては、乗算演算が最初に実行される言語ドキュメントがあるため、同じステートメントで乗算と加算を行うときに括弧を使用しない場合と同じです。

短絡に依存するのは「正しいこと」ですほとんどの場合に行います。それは、より少ない可動部品でより簡潔なコードにつながります。これは一般に、保守が容易であることを意味します。これは、CおよびC ++で特に当てはまります。

短絡操作に慣れていない(使用方法がわからない)人を雇うことを真剣に再検討します。

OK :) NULL変数にアクセスしないことを確認しているだけです。 実際、私は常に変数の操作を行う前に(また、コレクションのインデックス作成時など)このようなチェックを行います。

デフォルトではC#が条件を短絡するため、それは理にかなっています。 VBでは、開発者がANDALSOの代わりにANDを使用すると問題が発生する場合があります。

次のようなものと違うとは思わない:

INT* pNumber = GetAddressOfNumber();

if ((pNUmber != NULL) && (*pNumber > 0))
{
  // valid number, do whatever
}
else
{
  // On a null pointer, it drops to here, because (pNumber != NULL) fails
  // However, (*pNumber > 0), if used by itself, would throw and exception when dereferencing NULL
}

言語の機能を利用しているだけです。この種のイディオムは、Cがこの方法でブール式を実行し始めてから(または、どの言語が最初にそれを行ったとしても)一般的に使用されていると思います。

アセンブリにコンパイルしたのがcのコードである場合、正しい動作を短絡させるだけでなく、高速です。マシン言語では、ifステートメントの部分が次々と評価されます。短絡は遅くありません。

コードの作成には、企業にとって多額の費用がかかります。しかし、それを維持するにはもっと費用がかかります!

だから、私はあなたのポイントで大丈夫です:偶然、このコード行は、2年後にそれを読んで修正しなければならない人によってすぐには理解されないでしょう。

もちろん、彼は重大な生産上のバグを修正するよう求められます。彼はあちこち検索しますが、これに気付かないかもしれません。

私たちは常に次の人のためにコーディングするべきであり、彼は私たちほど賢くないかもしれません。私にとって、これは覚えておくべき唯一のことです。

そしてこれは、明らかな言語機能を使用し、他の機能を避けることを意味します。

最高、シルヴァン。

ちょっとしたトピックですが、このようにvb.netで同じ例を使用した場合

dim someString as string
someString = MagicFunction()
if not string.IsNullOrEmpty(someString) and someString.Length > 3 then
    ' normal string, do whatever
else
    ' do someting else
end if

これは、null(nothing)文字列で強打されますが、VB.Netでは、C#でも同じことを行うようにコーディングします

dim someString as string
someString = MagicFunction()
if not string.IsNullOrEmpty(someString) andalso someString.Length > 3 then
    ' normal string, do whatever
else
    ' do someting else
end if

andを追加すると、同じように動作し、読みやすくなります。 vbとc 'の両方の開発を行う誰かとして、2番目のvbはログインがわずかに異なるため、違いがあることを誰かに説明するのが簡単であることを示します。

Drux

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top