Як вставити новий рядок у рядковий літерал?


155

У .NET я можу надати обидва \rабо \nрядкові літерали, але є спосіб вставити щось на зразок "нового рядка" спеціального символу, як Environment.NewLineстатичну властивість?


9
Яке питання?
iburlakov

Відповіді:


319

Ну, прості варіанти:

  • string.Format:

    string x = string.Format("first line{0}second line", Environment.NewLine);
  • З'єднання рядків:

    string x = "first line" + Environment.NewLine + "second line";
  • Інтерполяція рядків (на C # 6 і вище):

    string x = $"first line{Environment.NewLine}second line";

Ви також можете використовувати \ n скрізь і замінити:

string x = "first line\nsecond line\nthird line".Replace("\n",
                                                         Environment.NewLine);

Зауважте, що ви не можете зробити цей рядок постійним , оскільки значення Environment.NewLineбуде доступне лише під час виконання.


1
Ну, звичайно, дякую, але я мав на увазі уникати використання Environment.NewLine, моє питання було, чи є '/ newline' буквальне.
Капітан Комік

2
@Captain: Чому ти хочеш уникати Environment.NewLine? Зовсім навпаки, це хороша практика використовувати його
абатищев

18
@abatishchev: У деяких місцях це хороша практика. У інших моїх це не так. Вам дійсно потрібно знати, що ви хочете використовувати конкретний для платформи. Наприклад, це не гарна ідея, якщо ви використовуєте мережевий протокол, який повинен визначати самі термінальні лінії.
Джон Скіт

1
@Captain Comic: Моє остаточне речення пояснює, чому це не може бути буквальним втечею - ви не можете включити його до метаданих для рядкової константи, оскільки це не постійне значення.
Джон Скіт

1
Так, можливо, я неохоче спричиняв обидва варіанти: один, який використовує оператор плюс, а другий, що використовує метод Формату, є досить накладними, де введення буквеного символу '\ newline' було б найшвидшим способом. Але, як сказав Джон, NewLine Literal, якщо вона існувала, повинна бути динамічною і залежною від платформи.
Капітан Комік

33

Якщо ви хочете рядок const, що містить у собі Environment.NewLine, ви можете зробити щось подібне:

const string stringWithNewLine =
@"first line
second line
third line";

EDIT

Оскільки це в рядку const, це робиться під час компіляції, тому інтерпретація нового рядка компілятора. Я, здається, не можу знайти посилання, що пояснює цю поведінку, але можу довести, що вона працює за призначенням. Я скомпілював цей код і в Windows, і в Ubuntu (з Mono), потім розібрав, і ось такі результати:

Розбирайте на Windows Розбирайте на Ubuntu

Як бачите, у Windows нові рядки трактуються як \ r \ n, а в Ubuntu як \ n


1
Компілятор автоматично додає Environment.NewLine між кожним рядком у тексті. Тож рядок інтерпретується як: "перший рядок" + Environment.NewLine + "другий рядок" + Environment.NewLine + "третій рядок"
Tal Jerome

3
+1 Мало відомий спосіб вставлення нових рядків у рядкові літерали. Чи є посилання на вказану вами поведінку? Це насправді Environment.NewLine чи це компілятор визначення нового рядка?
Гримаса відчаю

1
Ви впевнені, що сюди не вставляється символ редактора коду нового рядка? Якщо ви скопіюєте цей код в редактор Windows, він, ймовірно, перетвориться на \ r \ n. Зробіть те ж саме на платформі, схожій на Unix, і вона, ймовірно, замість цього перетвориться на \ n.
Xiyng

Слідкуйте за цим. Якщо ви скасуєте код на сервері CI / CD (наприклад, Teamcity, реєстрація на стороні сервера), він змінить CRLF на LF і не буде нових рядків у рядку.
Лешек П

13
var sb = new StringBuilder();
sb.Append(first);
sb.AppendLine(); // which is equal to Append(Environment.NewLine);
sb.Append(second);
return sb.ToString();

2
Чому б ви робили це, а не використовували, first + Environment.NewLine + secondякий є більш ефективним та (IMO) легше читати?
Джон Скіт

@Jon: Дійсно ефективніше? Я думав, що String.Formatвийде одночасно 1 рядок (але це всередині дещо повільно через специфічні для культури конкатенації тощо), а конкатенація рядків - 1 в результаті + 1 тимчасова, правда?
абатищев

1
@abatishchev: компілятор перетворює str + str + str в String.Concatenate, що безпосередньо будує лише один вихідний рядок (IIRC, якщо рядки є буквальними, конкатенація робиться в компіляторі.
Річард

@ Richard: тобто множинне, але однорядне об'єднання рядків ( "a"+b+"c"+dтощо) за продуктивністю дорівнює одному? Або просто перетворений на String.Concatenate(a,b,c,d,etc), правда?
абатищев

@abatishchev: Ось чому я не запропонував string.Formatу коментарі. З'єднання рядків не створюватиме тимчасових рядків, тому що компілятор буде викликати string.Concat(first, Environment.NewLine, second).
Джон Скіт

3

Ще один спосіб зручного розміщення Environment.NewLine у ​​рядку формату. Ідея полягає у створенні методу розширення рядка, який форматує рядок як завжди, але також замінює {nl} у тексті на Environment.NewLine

Використання

   " X={0} {nl} Y={1}{nl} X+Y={2}".FormatIt(1, 2, 1+2);
   gives:
    X=1
    Y=2
    X+Y=3

Код

    ///<summary>
    /// Use "string".FormatIt(...) instead of string.Format("string, ...)
    /// Use {nl} in text to insert Environment.NewLine 
    ///</summary>
    ///<exception cref="ArgumentNullException">If format is null</exception>
    [StringFormatMethod("format")]
    public static string FormatIt(this string format, params object[] args)
    {
        if (format == null) throw new ArgumentNullException("format");

        return string.Format(format.Replace("{nl}", Environment.NewLine), args);
    }

Примітка

  1. Якщо ви хочете, щоб ReSharper виділив ваші параметри, додайте атрибут до вищевказаного методу

    [StringFormatMethod ("формат")]

  2. Ця реалізація, очевидно, менш ефективна, ніж просто String.Format

  3. Можливо, той, хто зацікавився цим питанням, зацікавився б і наступним запитанням: Форматування іменних рядків у C #


2
string myText =
    @"<div class=""firstLine""></div>
      <div class=""secondLine""></div>
      <div class=""thirdLine""></div>";

це не все:

string myText =
@"<div class=\"firstLine\"></div>
  <div class=\"secondLine\"></div>
  <div class=\"thirdLine\"></div>";

1
static class MyClass
{
   public const string NewLine="\n";
}

string x = "first line" + MyClass.NewLine + "second line"

3
-1: Система вже визначає Environment.NewLine- дивіться інші відповіді.
Річард

@Richard: ОП, наскільки я міг його зрозуміти, хоче використовувати вбудований рядковий літерал, тобтоconst string
абатищев

@Richard Environment.NewLine статично не const

1

новіші версії .net дозволяють використовувати $ перед літералом, що дозволяє використовувати змінні всередині:

var x = $"Line 1{Environment.NewLine}Line 2{Environment.NewLine}Line 3";

1
Трохи контексту не було б погано.
croxy

1
Це не дає відповіді на запитання. Коли у вас буде достатня репутація, ви зможете коментувати будь-яку публікацію ; натомість надайте відповіді, які не потребують уточнення від запитувача . - З огляду
Х. Повелін

@ H.Pauwelyn ツ: Thx для зворотного зв'язку. Я додав трохи контексту. З моєї точки зору, рішення безумовно відповідає на питання.
DanielK

0

Якщо ви дійсно хочете, щоб рядок "Нова лінія" був постійним, тоді ви можете це зробити:

public readonly string myVar = Environment.NewLine;

Користувач ключового слова для читання лише в C # означає, що цю змінну можна призначити лише один раз. Ви можете знайти документацію по ньому тут . Це дозволяє оголосити постійну змінну, значення якої невідоме до часу виконання.


0

Мені більше подобається "пітонічний шлях"

List<string> lines = new List<string> {
    "line1",
    "line2",
    String.Format("{0} - {1} | {2}", 
        someVar,
        othervar, 
        thirdVar
    )
};

if(foo)
    lines.Add("line3");

return String.Join(Environment.NewLine, lines);

0

Якщо ви працюєте з веб-додатком, ви можете спробувати це.

StringBuilder sb = new StringBuilder();
sb.AppendLine("Some text with line one");
sb.AppendLine("Some mpre text with line two");
MyLabel.Text = sb.ToString().Replace(Environment.NewLine, "<br />")

0

Якщо я розумію питання: Пара, "\r\n"щоб отримати новий рядок нижче в textbox. Мій приклад спрацював -

   string s1 = comboBox1.Text;     // s1 is the variable assigned to box 1, etc.
   string s2 = comboBox2.Text;

   string both = s1 + "\r\n" + s2;
   textBox1.Text = both;

Типова відповідь може бути s1 s2 у text boxвикористанні певного типу стилю.


-1

Тут Environment.NewLine не працює.

Я поклав « < бр / > » в рядку і працював.

Наприклад:

ltrYourLiteral.Text = "Перший рядок <. бр / > Друга лінія.";

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.