2013-08-26 4 views
6

私はC#の古いコードのいくつかに取り組んでいましたが、私は悩ましいコードに遭遇しました。多くの苦もなく代入式を返す

が、それはこのような何かを行く:

private string foo(string _text) 
{ 
    /* some manipulation on _text */ 
    return _text = Server.HtmlDecode(_text); 
} 

それは私をいらだた最後の行です。私はCのバックグラウンドから来ており、コードが実際にデコードされた_text変数を返そうとしていることを理解できます。また、代入演算子の値は左のオペランドであるため、私はそれを見ることができます。

まだ私はそれが気がずっと分かります。

私は慣れておく必要があるC#の縦座標の練習ですか?

私に最後の行は、単に

return Server.HtmlDecode(_text); 

なく代入式でなければなりません。私が気づいていないより深いC#の機能はありますか?

+0

'_text'はグローバル変数ではありません。メソッドのパラメータです。 –

+0

割り当ては実際に必要ですか?後で '_text'で何もすることはできず、範囲外に出る可能性が最も高いです。 –

+0

@ lc。それは私が部分的に求めていたものです。何か意味があったら。私が集めたものに基づいて、私はそうは思わない。 –

答えて

10

を私はC#で古いコードの一部に取り組んでいましたが、私は私をうんざりコードに遭遇しました。

多くの面白い問題があります。それらをすべて列挙しましょう。

private string foo(string _text) 
{ 
    /* some manipulation on _text */ 
    return _text = Server.HtmlDecode(_text); 
} 

それは私

にコメントをいらいらもうんざりである最後の行です。ローカル変数は安価です。 _textの元の値を消去する必要はありません。代わりに、新しいローカル変数を作成し、それを操作します。こうすれば、メソッド内の任意の時点でをデバッグするときに、元の引数がであったことがわかります。 (元の議論は、変数が上書きされた瞬間にガベージコレクションの対象となるかもしれないので、永遠に失われる可能性があることを覚えておいてください。)非常に正当な理由なしに仮パラメータを上書きしないでください。デバッグが難しくなります。

代入演算子の値は左のオペランドであるため、わかります。

これは正しいですが、一般的には微妙に間違っています。 C#の代入演算子の値は、の右辺の値のオペランドになります。に関連付けられた型に変換されます。左手側に価値がないかもしれないことを忘れないでください。書き込み専用のプロパティーになる可能性があります。

私は慣れておく必要があるC#の縦座標練習ですか?

ここには標準的なプラクティスがあります。この使用方法について奇妙なことは、(1)選択された変数が正式であること、および(2)割り当てがreturnと組み合わされていることです。

言うためにC#での標準的な慣行のようになります。

string decoded = Server.HtmlDecode(_text); 
return decoded; 

今、あなたはこの魅力的な利点は、あなたが示唆するものの上にあるか疑問に思うかもしれません:

return Server.HtmlDecode(_text); 

答えは:前Visual Studio 2013では、デバッガにメソッド呼び出しの戻り値を調べる機能はありませんでした。したがって、あなたは次の選択肢を持っていたデバッグ中HtmlDecodeによって返された値が何だったか見てみたかった場合:

  • アセンブリレベルでのデバッグとHtmlDecode
  • にEAX
  • の内容で手順を見て、その状態を調べます現在の方法のうち
  • ステップと戻り値は、さもなければ無駄なローカル変数に結果を割り当て、次に、デバッガ
  • に局所を調べる
  • に割り当てられたどのような検討

最初の3つは恐ろしいもので、最後のものは簡単なので、これは多くのC#プログラマーがやっていることです。

あなたがこれを行うと、その後結果のローカルを使用しない場合は、C#コンパイラは、これが一般的な方法であると故意に警告「あなたはあなたがしてから読んだことがないローカルに書いた」抑制することを知っています。ローカルに定数が書かれている場合にのみ警告が表示されます。その場合は、コンパイル時に何を知っていて、通常はデバッガで検査する必要はありません。

VS2013がこの頻繁に要求されるこの機能をサポートするようになったら、この種のパターンは徐々に消えてしまうことでしょう。

+0

可能であれば、この発言を拡大してもよろしいですか? "元の議論は変数が上書きされた瞬間にガベージコレクションの対象となる可能性があり、したがって永遠に失われる可能性があります" –

+0

@Jace Kim:変数が上書きされると、引数にはライブ参照が残っていない可能性があります。 GCが収集することができます。 – InBetween

0

いいえ、それはやるべきことではなく、より多くのコードを1つの行に詰め込むという意味で、読みやすさを犠牲にしています。それはほとんど常に悪いことです。

この場合、実際には何の目的もありません。 _textはメソッドのパラメータであり、メソッド本体で変更すると何も成立しません。メソッドに渡された文字列は変更されません。

0

これらの結果は同じです。いいえ、深くあり

+0

私は 'Server.HtmlDecode(_text);'が好きです。つまり、私はローカルで宣言された文字列を使用して文字列操作を格納する方が好きです。 –

+0

私は気づいていない、または見つけられなかった、あいまいなC#機能があるかどうかを知りたかっただけです。 CとLispから来て、C#は背後にある多くの黒人雑誌だと思われる。 –

0

(私はそれはあなたが読んでいるコードにある道の上またはreturn Server.HtmlDecode(_text);ではなく、どちらかが好き)

_text = Server.HtmlDecode(_text); 
return _text; 

:それは後者の、またはを見るために最も一般ませんこの場合のC#の機能は、returnステートメントで代入するのは意味がありません。コードが行うべきことに従うことが難しくなります。

デコードされた値が_text変数に割り当てられていますが、その変数はもう使用されないので、メソッドが終了するときの値は何であるかは関係ありません。このパラメータは、メソッド内のローカル変数であり、メソッドの外側には何も影響しません。

+0

returnステートメントが_textの値または '代入式の結果'を返す場合、フォローアップの質問があります。それは非常に賢明な問題です。 C#のプログラマは '値の代入式'を使用していますか?私はCでの可読性のためにそれを避けましたが、私はそれを疲れさせるのに十分なコードを見ました。 –

+0

@JaceKim: 'return'ステートメントは式の値を返し、代入式の値は割り当てられた値です。戻り値は変数から再度読み取られません。 C#のプログラマは、割り当てを式として使用することがありますが、あまり頻繁ではありません。これは、ループが継続するかどうかを決定する値など、より複雑な制御構造である場合に使用されます。 'while((line = stream.ReadLine())!= null)... ' – Guffa

+0

ありがとうございます。それは非常に明確です。 –

2

この文は冗長で、ではなく、のC#の練習です。

ReSharperのがアクティブな状態でそうすることで、警告に

を与える割り当てられる値は、任意の実行パスで使用されていない

あなたが述べたように、このコードは確かにベストプラクティス

だろう
return Server.HtmlDecode(_text); 

また、デコードは_textの操作の一部であるため、割り当てを分離してstatemeを返すことも有効です、同じブロック内のロジックを保つために、NT:

/* Other manipulations on _text */ 
_text = Server.HtmlDecode(_text); 

return _text; 
関連する問題