web-dev-qa-db-ja.com

連鎖代入(つまり、a = b = c)の形式が悪いのはいつですか?

私はVB.Net WinFormsプロジェクトに取り組んでいて、次のようなコードを書いていることに気づきました。

this.Fizz.Enabled = this.Buzz.Enabled = someCondition;

それが悪いコードかどうか、私には判断できませんでした。割り当ての連鎖をいつ/いつ行わないかについての.NETガイドラインはありますか?

6
Jeff B

私はそれをしません。私は常に各割り当てを独自の行に配置しました。明快さは王様です。

実際には、チェーン割り当てを必要とするのに十分な状態変数を使用することはめったにありません。その時点に達したら、使用している状態の量を削減する方法を探し始めます。

22
Robert Harvey

それはプログラミング言語に依存します。変数の型が強制されない言語を使用すると、これが発生する可能性があります。

x = 1;
y = 494.0;
z = new Object();
x = y = z = "hello";

現在、x、y、zはすべて文字列です。後でコードで見つけた場合、これは混乱するかもしれません。

もう1つの問題は、オペレーターの過負荷です。一部の言語では、プロパティの左側の割り当てで行われる処理を変更できます。したがって、次のことが発生する可能性があります。

x = y.something = 0;

y.something0を返しません。 nullを返します。

それ以外の場合は、問題ありません。それが強く型付けされた言語であり、上記の事態が発生するリスクがない場合。その後、問題ありません。


もう1つの問題は、ソースコードの読み方です。

 a = b = c = new Object();

同じではありません。

 a = new Object();
 b = new Object();
 c = new Object();

本当にこんな感じです。

 c = new Object();
 b = c;
 a = b;

3つの変数すべてが同じ参照を持っていることは明らかでない場合があります。

6
Reactgular

これは必ずしも悪いコードではありませんが、コードの可読性が大幅に低下します。通常、私はそれを強くお勧めしますが、それが受け入れられる(または単にそれほど悪くない)場合がいくつかあると思います。たとえば、いくつかのローカル変数を定数値に設定する場合:

// accumulators
int j = 0, k = 0;
for(int i = 0; ...)
{
    ...
    if(reset)
    {
        // oops we have to start from the beginning
        i = j = k = 0;
    }
}

この場合、その行と、さらに重要なことに、それに付随するコメントは、執筆者がそれを書いたときの意図を明確にします。このコードには複合宣言も含まれていますが、これもお勧めしませんが、ここでも同じ理由で受け入れられます。

それでも、私はほとんどの場合それに対してお勧めします。 (機能的に同一である限り)より明示的なコードを作成しても害はありません。

3
p.s.w.g