Подтвердить что ты не робот

Объявление длинных строк, которые используют строчную интерполяцию в С# 6

Я обычно обертываю длинные строки, конкатенируя их:

Log.Debug("I am a long string. So long that I must " +
    "be on multiple lines to be feasible.");

Это совершенно эффективно, поскольку компилятор обрабатывает конкатенацию строковых литералов. Я также считаю, что это самый чистый способ справиться с этой проблемой (здесь перечислены параметры).

Этот подход хорошо работал с String.Format:

Log.Debug(String.Format("Must resize {0} x {1} image " +
    "to {2} x {3} for reasons.", image.Width, image.Height,
    resizedImage.Width, resizedImage.Height));

Однако теперь я никогда не хочу использовать String.Format снова в этих ситуациях, поскольку интерполяция строк С# 6 намного читаема. Я обеспокоен тем, что у меня больше нет эффективного, но чистого способа форматирования длинных строк.

Мой вопрос в том, может ли компилятор каким-то образом оптимизировать что-то вроде

Log.Debug($"Must resize {image.Width} x {image.Height} image " +
    $"to {resizedImage.Width} x {resizedImage.Height} for reasons.");

в приведенный выше эквивалент String.Format или если альтернативный подход, который я могу использовать, будет не менее эффективным (из-за ненужной конкатенации), в то же время сохраняя чистое структурирование моего кода (в соответствии с точками, поднятыми в ссылке выше).

4b9b3361

Ответ 1

В настоящее время такая оптимизация кажется невозможной.

Эта программа:

var name = "Bobby Tables";
var age = 8;
String msg = $"I'm {name} and" +
    $" I'm {age} years old";

скомпилирован, как если бы вы написали:

var name = "Bobby Tables";
var age = 8;
String msg = String.Concat(String.Format("I'm {0} and", name),
    String.Format(" I'm {0} years old", age));

Вы видите трудность в избавлении от Concat - компилятор переписал наши литералы интерполяции, чтобы использовать индексированные форматиры, ожидаемые String.Format, но каждая строка должна свести ее параметры от 0. Наивно их конкатенация заставит их вставлять name. Чтобы это получилось правильно, должно существовать состояние между вызовами парсера $, чтобы вторая строка была переформатирована как " I'm {1} years old". Альтернативно, компилятор может попытаться применить тот же анализ, что и для конкатенации строковых литералов. Я думаю, что это была бы юридическая оптимизация, хотя интерполяция строк может иметь побочные эффекты, но я не удивлюсь, если окажется, что это был угловой случай, при котором интерполированное конкатенация строк изменила поведение программы. Ничто не кажется невозможным, особенно учитывая, что логика уже существует для обнаружения аналогичного условия для строковых литералов, но я могу понять, почему эта функция не попала в первую версию.

Я бы написал код так, как вы считаете, самым чистым и читаемым, и не беспокойтесь о микро-неэффективности, если они не станут проблемой. Старая поговорка о коде, которая в первую очередь предназначена для понимания людьми, держится здесь.

Ответ 2

В специализированном случае использования этой строки в HTML (или синтаксическом разборке с любым парсером, где несколько пробелов не имеют значения), я мог бы порекомендовать вам использовать строки @$"" (строка с расширением строки), например:

[email protected]"some veeeeeeeeeeery long string {foo} 
whatever {bar}"

Ответ 3

Возможно, это было бы не так понятно, как с +, но, во что бы то ни стало, это возможно. Вам просто нужно разбить линию между { и }:

Log.Debug([email protected]"Must resize {image.Width} x {image.Height} image to {
    resizedImage.Width} x {resizedImage.Height} for reasons.");

SO coloring script не слишком хорошо справляется с этим синтаксисом, но компилятор С# делает; -)

Ответ 4

В С# 6.0:

var planetName = "Bob";
var myName = "Ford"; 
var formattedStr = $"Hello planet {planetName}, my name is {myName}!";
// formattedStr should be "Hello planet Bob, my name is Ford!"

Затем объедините с помощью stringbuilder:

StringBuilder stringBuilder = new StringBuilder();

stringBuilder.Append(formattedStr);
// Then add the strings you need 

Добавить больше строк в stringbuilder.....