противоречивое поведение со строкой + = int в c # - PullRequest
2 голосов
/ 31 августа 2010

Я смотрю на некоторый кодовый гольф в LINQPad и задаюсь вопросом, почему:

int c;
string o;

o+=c;//this works

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

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

главным образом, почему первый работает, а второй выбрасывает «неявное преобразование между« string »и« int »"ошибка.

Ответы [ 3 ]

4 голосов
/ 31 августа 2010

Оператор + в строках может принимать int, что приводит к другой строке.Тем не менее, не существует неявного (или явного) приведения из int в строку.

Когда вы используете тернарный оператор ?:, обе "ветви" должны быть либо одного типа, либо тип имеетбыть неявно конвертируемым к другому.

Во втором примере первая ветвь является строкой после выполнения оператора +, а вторая - просто int, поэтому она не работает.В третьем примере обе ветви являются строками, так что все нормально.

2 голосов
/ 31 августа 2010

Оператор += использует оператор +, поэтому первый действительно:

o = o + c;

То, что на самом деле создает компилятор:

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

Целое число заключено в квадрат, и вызывается метод Concat, который принимает параметры object. Метод ToString будет вызван для обоих параметров, чтобы получить их строковые значения, и они будут объединены.

Если вы сначала преобразуете целое число в строку, код становится более простым:

o += c.ToString();

, который становится:

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

Во втором коде типы в условном операторе не совпадают:

bool ? string : int

Второй и третий операнд должен иметь одинаковый тип, как в третьем коде:

bool ? string : string

Второй код действительно становится:

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

и третий код действительно становится:

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);
2 голосов
/ 31 августа 2010

Ваш второй нерабочий пример имеет несовместимые типы в операторе ?:.То, что у вас есть:

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

(Типы в скобках выше приведены, чтобы уточнить, какие существуют типы , а не приводить их к другому типу.)

Обе стороны : в троичном операторе должны быть одного типа.По этой причине ваш второй пример - синтаксическая ошибка.Третий пример работает, потому что конкатенация с пустой строкой приводит c к строке.

...