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

Сохранение структуры кода со строковым литералом, использующим пробельные символы

Итак, немного странный вопрос, который у меня возникли проблемы с поисковыми условиями. Если у меня есть многострочный строковый литерал в моей программе, все равно, чтобы сохранить отступ моего кода без добавления нежелательного пробела в строковый литерал?

Пример:

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 переменными внутри)?

4b9b3361

Ответ 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?

Надеюсь, этого достаточно, чтобы начать работу над решением.