Сохранение структуры кода со строковым литералом, использующим пробельные символы
Итак, немного странный вопрос, который у меня возникли проблемы с поисковыми условиями. Если у меня есть многострочный строковый литерал в моей программе, все равно, чтобы сохранить отступ моего кода без добавления нежелательного пробела в строковый литерал?
Пример:
if (true)
{
if (!false)
{
//Some indented code;
stringLiteral = string.format(
@"This is a really long string literal
I don't want it to have whitespace at
the beginning of each line, so I have
to break the indentation of my program
I also have vars here
{0}
{1}
{2}",
var1, var2, var3);
}
}
Вероятно, это просто мой разговор с OCD, но он все равно поддерживает отступы моей программы, не добавляя нежелательные пробелы в строку, или их нужно строить по строкам (настоящая строка - это супер длинный string.format, который является 20 строк с 12 переменными внутри)?
Ответы
Ответ 1
Я бы полностью отделил его от отдельного статического класса или ресурса:
public static class MyStringResources
{
public static readonly string StringLiteral =
@"This {0} a really long string literal
I don't want {1} to have {2} at
the beginning of each line, so I have
to break the indentation of my program";
}
С использованием, например:
stringLiteral = String.Format(MyStringResources.StringLiteral, var1, var2, var3);
Еще лучше, таким образом, вы можете иметь хорошую функцию, которая требует количества ожидаемых переменных:
public static class MyStringLiteralBuilder
{
private static readonly string StringLiteral =
@"This {0} a really long string literal
I don't want {1} to have {2} at
the beginning of each line, so I have
to break the indentation of my program";
public static string Build(object var1, object var2, object var3)
{
return String.Format(MyStringResources.StringLiteral, var1, var2, var3);
}
}
Затем вы не можете случайно пропустить переменные (и, возможно, даже сильно называть их номерами, булевыми и т.д.)
stringLiteral = MyStringLiteralBuilder.Build(var1, var2, var3);
stringLiteral = MyStringLiteralBuilder.Build(var1, var2); //compiler error!
Конечно, в этот момент вы можете делать все, что захотите, с этими строителями. Создайте новый создатель для каждого специального большого "stringLiteral", который у вас есть в вашей программе. Возможно, вместо того, чтобы иметь их static
, они могут быть экземплярами, которые вы можете получить/установить свойства ключа, тогда вы также можете дать им хорошие имена:
public class InfoCardSummary
{
public string Name { get; set; }
public double Age { get; set; }
public string Occupation { get; set; }
private static readonly string FormattingString =
@"This person named {0} is a pretty
sweet programmer. Even though they're only
{1}, Acme company is thinking of hiring
them as a {2}.";
public string Output()
{
return String.Format(FormattingString, Name, Age, Occupation);
}
}
var info = new InfoCardSummary { Name = "Kevin DiTraglia", Age = 900, Occupation = "Professional Kite Flier" };
output = info.Output();
Ответ 2
Определите константу строки в другом файле и используйте идентификатор в коде. Это хорошая практика, чтобы все ваши строки были в одном месте, если вам нужно их перевести, проверить на соответствие и т.д.
Ответ 3
if (true)
{
if (!false)
{
//Some indented code;
stringLiteral = string.format(
"This is a really long string literal. " +
"I don't want it to have whitespace at " +
"the beginning of each line, so I have " +
"to break the indentation of my program " +
"I also have vars here: " +
"{0} " +
"{1} " +
"{2}",
var1, var2, var3);
// OR, with lineskips:
stringLiteral = string.format(
"This is a really long string literal\r\n" +
"I don't want it to have whitespace at \r\n" +
"the beginning of each line, so I have\r\n" +
"to break the indentation of my program\r\n"
"I also have vars here\r\n" +
"{0}\r\n" +
"{1}\r\n" +
"{2}\r\n",
var1, var2, var3);
}
}
Не красиво, но работает.
Ответ 4
Грамматика для языка С# допускает два способа указания строковых литералов:
- Здесь-doc/at-string (
@"..."
), который может охватывать строки исходного файла, или
- Типичный строковый литерал (
"..."
), который не может быть.
Другие способы получения желаемого эффекта:
Альтернатива, в духе других ответов, пытающихся сделать ее более приятной:
static readonly string MultilineLiteral = string.Join( Environment.NewLine , new string[]{
@"line 1" ,
"line 2" ,
@"line 3" ,
. . .
"line n" ,
}) ;
Ответ 5
При объединении строк @verbatim и новой интерполяции $string вы можете применить следующий трюк: внутри {и} это выражение (следовательно, код), а не строковые данные. Поместите свою новую строку и ваш отступ там, и она не будет отображаться в форматированной строке. Если ваш текст не содержит выражений, вам нужно будет использовать пустое выражение. Я пробовал {}, но, к сожалению, это не работает: выражение ожидаемая ошибка. Как минимум используйте {nl}, назначив пустую строку nl. Newline nl или {wrap} или что-то в этом роде.
using System;
namespace ConsoleApplication6
{
class Program
{
static void Main(string[] args)
{
int count = 123;
string nl = string.Empty;
Console.WriteLine([email protected]"Abc {count} def {count
} ghi {
count} jkl{nl
} mno");
Console.ReadLine();
}
}
}
Вывод:
Abc 123 def 123 ghi 123 jkl mno
Ответ 6
В моем случае было приемлемо сделать способ расширения следующим образом:
class Program
{
static void Main(string[] args)
{
var code = [email protected]"
public static loremIpsum(): lorem {{
return {{
lorem: function() {{
return 'foo'
}},
ipsum: function() {{
return 'bar'
}},
dolor: function() {{
return 'buzz'
}}
}}
}}".AutoTrim();
Console.WriteLine(code);
}
}
static class Extensions
{
public static string AutoTrim(this string code)
{
string newline = Environment.NewLine;
var trimLen = code
.Split(newline)
.Skip(1)
.Min(s => s.Length - s.TrimStart().Length);
return string.Join(newline,
code
.Split(newline)
.Select(line => line.Substring(Math.Min(line.Length, trimLen))));
}
}
![введите описание изображения здесь]()
Ответ 7
Я тоже столкнулся с этой проблемой.
Несколько раз я помещал всю вещь в одну строку с помощью \n
(или \r\n
для dos/windows).
Несколько раз я просто игнорирую уродливое форматирование кода.
В других случаях я помещаю текст в другое место - я думаю, что в С# у вас есть #define или даже в отдельном файле или базе данных в зависимости от строки. Вам все равно придется заменить переменную - в С# я думаю, что вы используете string.Format?
Надеюсь, этого достаточно, чтобы начать работу над решением.