2

私はLINQPadでいくつかのコードゴルフを見ていて、なぜだろうと思っています:

int c;
string o;

o+=c;//this works

o+=P==2?"."+c:c;//this doesn't

o+=P==2?"."+c:""+c;//this does

主に、最初のものが機能し、2番目のものが「'string'と'int'の間の暗黙の変換なし」エラーをスローする理由。

4

3 に答える 3

4

文字列の+演算子はintを受け入れることができ、結果として別の文字列になります。ただし、intからstringへの暗黙的(または明示的)キャストはありません。

三項演算子を使用する場合?:、両方の「ブランチ」が同じタイプであるか、一方のタイプが暗黙的に他方に変換可能である必要があります。

2番目の例では、+演算子が実行された後の最初のブランチは文字列ですが、2番目のブランチは単なるintであるため、機能しません。3番目の例では、両方のブランチが文字列であるため、問題ありません。

于 2010-08-31T15:54:20.430 に答える
2

+=オペレーターはオペレーターを使用するので+、最初は実際には次のとおりです。

o = o + c;

コンパイラが実際に作成するのは次のとおりです。

o = String.Concat((object)o, (object)c);

整数はボックスで囲まれ、パラメーターを受け取るConcatメソッドobjectが呼び出されます。メソッドは両方のToStringパラメーターで呼び出され、文字列値を取得し、連結されます。

最初に整数を文字列に変換すると、コードはより単純になります。

o += c.ToString();

これは次のようになります。

o = String.Concat(o, c.ToString());

2番目のコードでは、条件演算子の型が一致していません。

bool ? string : int

2番目と3番目のオペランドは、3番目のコードのように、同じタイプである必要があります。

bool ? string : string

2番目のコードは実際には次のようになります。

o = String.Concat(
  o,
  P == 2
    ? String.Concat((object)".", (object)c)
    : c
);

そして3番目のコードは実際には次のようになります。

o = String.Concat(
  o,
  P == 2
    ? String.Concat((object)".", (object)c)
    : String.Concat((object)String.Empty, (object)c)
);

とにかく、演算子StringBuilderを使用する代わりに、を使用して文字列を作成することを検討する必要があります。+=

StringBuilder builder = new StringBuilder;

if (P == 2) {
  builder.Append('.');
}
builder.Append(c);
于 2010-08-31T16:03:51.247 に答える
2

2番目の機能しない例では、?:演算子に一貫性のないタイプがあります。あなたが持っているものは:

o += (P == 2 ? (string) "." + c : (int) c);

(上記の括弧内のタイプは、既存のタイプが何であるかを明確にするためのものであり、別のタイプにキャストするためのものではありません。)

三項演算子の両側は:同じタイプである必要があります。このため、2番目の例は構文エラーです。空の文字列との連結は文字列に強制cされるため、3番目の例は機能します。

于 2010-08-31T15:53:05.817 に答える