メソッドがfalseを返すかどうかの確認:結果を一時変数に割り当てるか、メソッド呼び出しを条件付きで直接配置しますか?


9

ifステートメントでtrueまたはfalseの値を返すメソッドを呼び出すのは良い習慣ですか?

このようなもの:

private void VerifyAccount()
{
    if (!ValidateCredentials(txtUser.Text, txtPassword.Text))
    {
        MessageBox.Show("Invalid user name or password");
    }
}

private bool ValidateCredentials(string userName, string password)
{
    string existingPassword = GetUserPassword(userName);
    if (existingPassword == null)
        return false;

    var hasher = new Hasher { SaltSize = 16 };
    bool passwordsMatch = hasher.CompareStringToHash(password, existingPassword);

    return passwordsMatch;
}

または、それらを変数に格納してから、次のような値を使用して比較する方が良いでしょう

bool validate = ValidateCredentials(txtUser.Text, txtPassword.Text);
if(validate == false){
    //Do something
}

私は.NETだけでなく、すべてのプログラミング言語の質問にも言及しています。例として.NETを使用しただけです


3
一時変数を使用する場合は、if (!validate)ではなく書き込みif (validate == false)ます。
フィリップ

12
私はあなたがそれをブールそれ以外ははい、その良い練習を返すべきである知っているので「)CredentialsAreValid(」のような機能なものに名前を付けるだろう
ザカリーK

3
IsValidCredentials文法的には厄介ですが、ブール値の戻り値を示すための一般的な形式です。
zzzzBov

@Philip if(!validate)とthis if(validate)の違いは何ですか?
KyelJmD 2012

!「NOT」演算子であり、ブール式を否定します。だから、if (!validate)の反対ですif (validate)。ifステートメントvalidateは、trueでない場合に入力されます。
フィリップ

回答:


26

これらすべてのものと同様に、状況によって異なります。

への呼び出しの結果を使用しない場合はValidateCredentials、結果をローカル変数に格納する必要はありません(デバッグ目的以外)。ただし、それによってコードが読みやすくなり(したがって、保守性が向上し)、変数がそれに対応できるようになる場合。

このコードは、それほど効率的ではありません。


1
そのタイプは読みやすいですか?上記と
同じ

@KyelJmD:それはプログラミングしている文化に依存します。私がプログラミングした場所!ValidateCredentialsでは、コードで何をしているのかを明示的に示しているので、より読みやすくなっています。それは非常に明確です。呼び出す関数に「自己文書化」名がない場合は、変数を使用することをお勧めします。現状では、変数を省略して、自己文書化したコードをそのまま使用することをお勧めします。
Joel Etherton、2015

そもそもValidateCredentialsは判読できません。名前からどのように結果の意味がわかりますか?CredentialsAreValidまたはCredentialsAreInvalidのどちらかがはるかに優れています。
gnasher729 2015

9

追加の変数を使用する理由 私は最初のアプローチを使用することを好みます、それはより読みやすくてシンプルです。


4

ifステートメントでtrueまたはfalseの値を返すメソッドを呼び出すのは良い習慣ですか?

はい、条件文がインライン化して読みやすくするほど単純ではない場合。

または、それらを変数に格納してから、次のような値を使用して比較する方が良いでしょう

複数の場所で値を使用する場合、またはコードを読みやすくするために値が必要な場合にのみ、これを行う必要があります。それ以外の場合、変数への割り当ては不要です。不要なコードはせいぜい無駄であり、最悪の場合は欠陥の原因です。


2

見てみましょう...

それはすべてKISSに関するものなので、それなしで実行できる場合は追加の変数を作成する必要はありません。また、入力する必要はありません...必要がない場合。

しかし、その後DRYしているので、後で呼び出しValidateCredentialsて自分で入力しValidateCredentials(txtUser.Text, txtPassword.Text)ている場合は、追加の変数を作成する必要があります。


2

はい、通常、条件などの方法を使用することで問題ありません。ただし、メソッド名がメソッドがブール値を返すことを示している場合は役立ちます。たとえば、CanValidateCredentials。Cスタイルの言語では、このメソッドは多くの場合、IsおよびCanプレフィックスの形式をとり、Rubyでは「?」サフィックス。


1
メソッド名については良い点ですが、メソッド名を「if」で始めることは決してありません。次に、コードは「if if」を読み取ります。「できる」は大丈夫です:if (cat.canOpenCanOfCatFood())
ケビンクライン

ありがとう、@ Kevin。「もし」ではなく「である」を意味しました。回答を編集しました
クリスチャンホースダル

1

まだ指摘されていないもう1つの懸念があります。短絡評価です。これら2つのコードフラグメントの違いは何ですか?

例#1:

if(foo() && bar() && baz())
{
    quz();
}

例#2:

bool isFoo = foo();
bool isBar = bar();
bool isBaz = baz();
if(isFoo && isBar && isBaz)
{
    quz();
}

これら2つのコードフラグメントは同じことを行うように見えますが、言語が短絡評価をサポートしている場合、これら2つのフラグメントは異なります。短絡評価とは、コードが条件をパスまたは失敗するために必要な最小限の値を評価することを意味します。例1の場合、foo()がfalseを返すと、bar()とbaz()は評価されません。これは、foo()がfalseを返すか、foo()がtrueを返し、bar()がfalseを返す場合にスキップできるため、baz()が長時間実行される関数呼び出しである場合に役立ちます。

これは、例2には当てはまりません。foo()、bar()、およびbaz()は常に評価されます。bar()とbaz()が副作用を示すと予想している場合は、例1で問題が発生します。上記の例1は、実際にはこれと同等です。

例#3:

if(foo())
{
    if(bar())
    {
        if(baz())
        {
            quz();
        }
    }
}

例1と2を選択するときは、コードのこれらの違いに注意してください。


1

読みやすさの問題について少し拡大...

結果を変数に格納する2つの正当な理由を考えることができます。

  1. 条件を複数回使用する場合は、変数に保存することで、関数を1回呼び出すだけで済みます。(これは、格納された値がまだ有効であることを前提としています。それを再テストする必要がある場合、もちろんこれは適用されません。)

  2. 変数に格納すると、関数呼び出しで表示されるものよりも意味のある名前を条件に付けることで、読みやすさが向上します。

たとえば、これ:

bool foo_is_ok = is_ok(foo);
if (foo_is_ok) ...

読みやすさの助けにはなりませんが、これは:

bool done_processing = feof(file1) && feof(file2);
if (done_processing) ...

すぐにはわかりませんが、feof(file1) && feof(file2)処理が完了したことを意味するためです。

passwordsMatch問題の変数はおそらく私のものより良い例です。

使い捨て変数は、値に意味のある名前を付ける場合に役立ちます。(これはもちろん人間の読者のためにです。)


done_processing変数を紹介するのではなく、コメントを削除したいと思います。結局のところ、名前done_processingはコメントの役割を果たします。そして、実際のコメントでこの条件が処理が完了したことを通知する理由について1、2語言うことができます。ただし、私は優れたコメンターではありませんが、おそらく実際のコードではどちらも行いません...
cmaster-モニカを復活させる

@cmaster:コメントに関する問題の1つは、コメントとコードとの同期が非常に簡単に取れなくなることです。名前付き変数done_processingは、意図を表現するためのより永続的な方法です。
キース・トンプソン

ポイント番号2の+1-よく名前が付けられたtemp varが実際に明確になる場合があります。
user949300
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.