メソッドのパラメーターを再利用するのは悪い習慣ですか?


12

メソッド自体からメソッドに渡される値を変更する必要がある場合があります。例として、このメソッドのような文字列をサニタイズします:

void SanitizeName(string Name)
{
    Name = Name.ToUpper();

    //now do something here with name
}

Name引数は参照渡しではないため、これはまったく無害です。ただし、何らかの理由で、将来開発者がすべての値をrefで渡すことにした場合、文字列のサニタイズはメソッドの外部の値に影響を及ぼし、有害な結果を招く可能性があります。

したがって、引数自体に再割り当てする代わりに、常に次のようなローカルコピーを作成します。

void SanitizeName(string Name)
{
    var SanitizedName = Name.ToUpper();

    //now do something here with name
}

これにより、値が渡される方法を変更してもメソッドの外での進行に影響を与えないことが保証されますが、これについて過度に妄想を立てているのではないかと思います。


1
はい、それは悪い習慣です。いいえ、それは無害ではありません。この行Name = Name.ToUpper();は、Name変更の価値としてあなたの頭の中でコードを追跡するのを難しくします。2番目の例は、将来を保証するだけでなく、何をしているのかを推論するのも簡単です。
デビッドアルノ

2
しかし、どうif (param == NULL) param = default_value;ですか?
aragaer

はい/いいえほど簡単ではないと思います。
MrSmith42

3
場合は、「将来的には、開発者が参照によって渡されたすべての値を持っていることを決定した」、私はおそらく付き引数を持っているだろうとDEV、パラメータの再利用が関与か;-)正直なところ、1は値渡しすることを決定したときにby refすることを渡されていませんでした何らかの方法でローカルアクセスを非ローカルアクセスに変換するため、彼は常に結果を慎重にチェックする必要があります。
ドックブラウン

2
私は主に私たちは再割り当てすることはありませんパラダイムで働くすべての変数を。今まで。少数の変数を再割り当てする必要があるかどうかに苦労している人を想像するのは面白いです。
カールビーレフェルト

回答:


10

プロジェクトのコーディング規約に依存すると思います。

私は個人的に、finalすべての変数とパラメーターに自動的にキーワードを追加しました。この方法では、パラメーターが再利用されているかどうかが一目でわかります。

私の仕事のプロジェクトでは、パラメータを再利用することはお勧めしませんが、たとえば.trim()nullケースで呼び出すかデフォルトを設定するだけの場合は、ほとんどの場合パラメータを再利用します。パラメータの再利用よりも。

名前がそのコンテンツを参照しなくなるため、パラメーターを再利用してまったく異なるコンテンツを保存しないでください。ただし、これは変数の再割り当てすべてに当てはまり、パラメータに限定されません。

したがって、チームと協力して、この問題をカバーするコーディング規約を策定してください。


0

セキュリティの目的で静的コードアナライザーを使用すると、混乱する可能性があり、使用前に入力パラメーター変数を検証またはサニタイズしていないと思われる場合があります。Nameたとえば、SQLクエリで使用すると、SQLインジェクションの脆弱性が主張される可能性があり、説明に時間がかかります。それは悪いです。一方、実際に入力をサニタイズせずに、サニタイズされた入力に明確に名前が付けられた変数を使用することは、単純なコードアナライザーを簡単に静めるための簡単な方法です(偽陰性の脆弱性発見)。


また、ほとんどの場合、何らかの注釈または特別なコメントを使用して、これが意図されたリスクであり、気付かないリスクではないことをコードアナライザーに示すこともできます。
MrSmith42

0

これに対する答えは、誰がコードを読むかによって100%異なります。どのスタイルが最も役立つと思いますか?

最も一般的なケースは、値を関数引数に再割り当てすることを避けることです。開発者の多くは、関数呼び出しがどのように機能するかについての精神モデルを持っているためです。この問題は、各関数を呼び出す引数の値を出力するデバッガーによって悪化する可能性があります。引数を編集する場合、この情報は技術的には正しくなく、奇妙なフラストレーションを招く可能性があります。

そうは言っても、メンタルモデルは変わります。特定の開発環境では、name「この時点での名前の最適な表現」であることが望ましい場合があります。途中で値に何らかの変更を加えたとしても、作業中の変数をより明示的に引数にリンクすることが望ましい場合があります。かさばるオブジェクトを作成するのではなく、特定の変数を再利用することで、実行時の利点が大きくなる場合があります。結局のところ、4GBの文字列を使用している場合は、作成する必要のある余分なコピーの数を最小限に抑えることをお勧めします。


-1

あなたのコード例には完全に異なる問題があります:

メソッドの名前はSanitizeNameです。この場合、名前のサニタイズが期待されます。それは、あなたがあなたの機能を読者に伝えるものだからです。

唯一あなたが機能の事、やるべきは、されて消毒与えられた名前を。あなたのコードを読まずに、私は次のことを期待します:

string SanitizeName(string Name)
{
    //somehow sanitize the name
    return Result;
}

ただし、メソッドは単にサニタイズする以上のことを行うことを意味します。それはコードのにおいであり、避けるべきです。

あなたの質問ではありません:メソッドパラメータを再利用するのは悪い習慣ですか? さらに、副作用と予期しない動作は悪い習慣ですか?

その答えは明確です:はい!

Name引数は参照によって渡されないため、これは純粋に無害です。ただし、何らかの理由で、将来開発者がすべての値をrefで渡すことにした場合、文字列のサニタイズはメソッドの外部の値に影響を及ぼし、有害な結果を招く可能性があります

何も返さないことで読者を誤解させます。メソッド名は、で何かをしていることを明確に示していますName。それで、結果はどこに行くべきですか?あなたの関数のシグネチャがによってvoid読み込み私が使用していないNameが、どちらもIDに害を行い、また結果(明示的)をご紹介します。おそらく例外がスローされますが、そうでない場合があります。しかし、Name変更されていません。これはメソッド名とは反対の意味です。

問題は副作用よりも再利用です。副作用を防ぐために、変数を再利用しないでください。副作用がない場合は問題ありません。


4
-1これは元の質問には答えません。提供されているコードは、手元の質問を表示するための単なるサンプルコードです。提供されたサンプルコードを「攻撃」/レビューする代わりに、質問に答えてください。
ニクラスH

1
@NiklasHこれは質問に完全に答えます:関数内のパラメーターを操作し、TOが言及したように誤ってコピーではなく参照を操作すると、これは副作用を引き起こします(私が言ったように)これは悪いです。メソッド名を慎重に選択して(Rubyの「!」と考えてください)、および/または戻り値の型を選択して、変数を変更することを示すことを防ぐために。変数を変更しない場合は、コピーのみで作業してください。
トーマスジャンク
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.